mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
cleanup
This commit is contained in:
@@ -26,50 +26,48 @@ import com.intellij.openapi.components.impl.BasePathMacroManager
|
||||
import com.intellij.openapi.components.impl.stores.DirectoryStorageData
|
||||
import com.intellij.openapi.components.impl.stores.StateStorageManager
|
||||
import com.intellij.openapi.components.impl.stores.StorageData
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.util.NamedJDOMExternalizable
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.util.messages.MessageBus
|
||||
|
||||
public class ApplicationPathMacroManager : BasePathMacroManager(null)
|
||||
class ApplicationPathMacroManager : BasePathMacroManager(null)
|
||||
|
||||
class ApplicationStoreImpl(private val myApplication: ApplicationImpl, pathMacroManager: PathMacroManager) : ComponentStoreImpl() {
|
||||
private val myStateStorageManager: StateStorageManager
|
||||
class ApplicationStoreImpl(private val application: ApplicationImpl, pathMacroManager: PathMacroManager) : ComponentStoreImpl() {
|
||||
private val stateStorageManager: StateStorageManager
|
||||
|
||||
companion object {
|
||||
private val DEFAULT_STORAGE_SPEC = "${StoragePathMacros.APP_CONFIG}/${PathManager.DEFAULT_OPTIONS_FILE_NAME}${DirectoryStorageData.DEFAULT_EXT}"
|
||||
}
|
||||
|
||||
init {
|
||||
myStateStorageManager = object : StateStorageManagerImpl(pathMacroManager.createTrackingSubstitutor(), ROOT_ELEMENT_NAME, myApplication, myApplication.getPicoContainer()) {
|
||||
private var myConfigDirectoryRefreshed: Boolean = false
|
||||
stateStorageManager = object : StateStorageManagerImpl(pathMacroManager.createTrackingSubstitutor(), "application", application, application.getPicoContainer()) {
|
||||
private var configDirectoryRefreshed = false
|
||||
|
||||
override fun createStorageTopicListener(): StateStorage.Listener? {
|
||||
return myApplication.getMessageBus().syncPublisher(StateStorage.STORAGE_TOPIC)
|
||||
}
|
||||
override fun createStorageTopicListener() = application.getMessageBus().syncPublisher(StateStorage.STORAGE_TOPIC)
|
||||
|
||||
override fun createStorageData(fileSpec: String, filePath: String): StorageData {
|
||||
return StorageData(ROOT_ELEMENT_NAME)
|
||||
}
|
||||
override fun createStorageData(fileSpec: String, filePath: String) = StorageData(rootTagName)
|
||||
|
||||
override fun getOldStorageSpec(component: Any, componentName: String, operation: StateStorageOperation): String? {
|
||||
if (component is NamedJDOMExternalizable) {
|
||||
return StoragePathMacros.APP_CONFIG + '/' + component.getExternalFileName() + DirectoryStorageData.DEFAULT_EXT
|
||||
return "${StoragePathMacros.APP_CONFIG}/${component.getExternalFileName()}${DirectoryStorageData.DEFAULT_EXT}"
|
||||
}
|
||||
else {
|
||||
return DEFAULT_STORAGE_SPEC
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMacroSubstitutor(fileSpec: String) = if (fileSpec == StoragePathMacros.APP_CONFIG + '/' + PathMacrosImpl.EXT_FILE_NAME + DirectoryStorageData.DEFAULT_EXT) null else super.getMacroSubstitutor(fileSpec)
|
||||
override fun getMacroSubstitutor(fileSpec: String) = if (fileSpec == "${StoragePathMacros.APP_CONFIG}/${PathMacrosImpl.EXT_FILE_NAME}${DirectoryStorageData.DEFAULT_EXT}") null else super.getMacroSubstitutor(fileSpec)
|
||||
|
||||
override fun isUseXmlProlog() = false
|
||||
|
||||
override fun beforeFileBasedStorageCreate() {
|
||||
if (myConfigDirectoryRefreshed || (!myApplication.isUnitTestMode() && !myApplication.isDispatchThread())) {
|
||||
if (configDirectoryRefreshed || (!application.isUnitTestMode() && !application.isDispatchThread())) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
val configPath = getMacrosValue(StoragePathMacros.ROOT_CONFIG)
|
||||
if (configPath == null) {
|
||||
val configPath = expandMacros(StoragePathMacros.ROOT_CONFIG)
|
||||
if (configPath == StoragePathMacros.ROOT_CONFIG) {
|
||||
LOG.warn("Macros ROOT_CONFIG is not defined")
|
||||
return
|
||||
}
|
||||
@@ -80,24 +78,13 @@ class ApplicationStoreImpl(private val myApplication: ApplicationImpl, pathMacro
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myConfigDirectoryRefreshed = true
|
||||
configDirectoryRefreshed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMessageBus(): MessageBus {
|
||||
return myApplication.getMessageBus()
|
||||
}
|
||||
override fun getMessageBus() = application.getMessageBus()
|
||||
|
||||
override fun getStateStorageManager(): StateStorageManager {
|
||||
return myStateStorageManager
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(javaClass<ApplicationStoreImpl>())
|
||||
|
||||
private val DEFAULT_STORAGE_SPEC = StoragePathMacros.APP_CONFIG + "/" + PathManager.DEFAULT_OPTIONS_FILE_NAME + DirectoryStorageData.DEFAULT_EXT
|
||||
private val ROOT_ELEMENT_NAME = "application"
|
||||
}
|
||||
override fun getStateStorageManager() = stateStorageManager
|
||||
}
|
||||
|
||||
@@ -19,66 +19,58 @@ import com.intellij.openapi.components.PathMacroManager
|
||||
import com.intellij.openapi.components.PathMacroSubstitutor
|
||||
import com.intellij.openapi.components.impl.stores.StateStorageManager
|
||||
import com.intellij.openapi.components.impl.stores.StorageData
|
||||
import com.intellij.openapi.project.impl.ProjectManagerImpl
|
||||
import org.jdom.Element
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
val VERSION_OPTION: String = "version"
|
||||
abstract class BaseFileConfigurableStoreImpl(protected val pathMacroManager: PathMacroManager) : ComponentStoreImpl() {
|
||||
val storageManager by Delegates.lazy { createStorageManager() }
|
||||
|
||||
abstract class BaseFileConfigurableStoreImpl(protected val myPathMacroManager: PathMacroManager) : ComponentStoreImpl() {
|
||||
private var myStateStorageManager: StateStorageManager? = null
|
||||
override fun getStateStorageManager() = storageManager
|
||||
|
||||
public open class BaseStorageData : StorageData {
|
||||
private var myVersion = ProjectManagerImpl.CURRENT_FORMAT_VERSION
|
||||
override fun getPathMacroManagerForDefaults() = pathMacroManager
|
||||
|
||||
public constructor(rootElementName: String) : super(rootElementName) {
|
||||
}
|
||||
protected abstract fun createStorageManager(): StateStorageManager
|
||||
}
|
||||
|
||||
protected constructor(storageData: BaseStorageData) : super(storageData) {
|
||||
}
|
||||
open class ProjectStorageData : StorageData {
|
||||
companion object {
|
||||
val CURRENT_FORMAT_VERSION = 4
|
||||
val VERSION_OPTION: String = "version"
|
||||
}
|
||||
|
||||
override fun load(rootElement: Element, pathMacroSubstitutor: PathMacroSubstitutor?, intern: Boolean) {
|
||||
super.load(rootElement, pathMacroSubstitutor, intern)
|
||||
private var version = CURRENT_FORMAT_VERSION
|
||||
|
||||
val v = rootElement.getAttributeValue(VERSION_OPTION)
|
||||
myVersion = if (v == null) ProjectManagerImpl.CURRENT_FORMAT_VERSION else Integer.parseInt(v)
|
||||
}
|
||||
constructor(rootElementName: String) : super(rootElementName) {
|
||||
}
|
||||
|
||||
override fun save(newLiveStates: Map<String, Element>): Element {
|
||||
var root = super.save(newLiveStates)
|
||||
if (root == null) {
|
||||
root = Element(myRootElementName)
|
||||
}
|
||||
writeOptions(root, Integer.toString(myVersion))
|
||||
return root
|
||||
}
|
||||
protected constructor(storageData: ProjectStorageData) : super(storageData) {
|
||||
}
|
||||
|
||||
protected open fun writeOptions(root: Element, versionString: String) {
|
||||
root.setAttribute(VERSION_OPTION, versionString)
|
||||
}
|
||||
override fun load(rootElement: Element, pathMacroSubstitutor: PathMacroSubstitutor?, intern: Boolean) {
|
||||
super.load(rootElement, pathMacroSubstitutor, intern)
|
||||
|
||||
override fun clone(): StorageData {
|
||||
return BaseStorageData(this)
|
||||
}
|
||||
version = rootElement.getAttributeValue(VERSION_OPTION)?.toInt() ?: CURRENT_FORMAT_VERSION
|
||||
}
|
||||
|
||||
override fun getChangedComponentNames(newStorageData: StorageData, substitutor: PathMacroSubstitutor?): Set<String>? {
|
||||
val data = newStorageData as BaseStorageData
|
||||
if (myVersion != data.myVersion) {
|
||||
return null
|
||||
}
|
||||
return super.getChangedComponentNames(newStorageData, substitutor)
|
||||
override fun save(newLiveStates: Map<String, Element>): Element {
|
||||
var root = super.save(newLiveStates)
|
||||
if (root == null) {
|
||||
root = Element(myRootElementName)
|
||||
}
|
||||
writeOptions(root, Integer.toString(version))
|
||||
return root
|
||||
}
|
||||
|
||||
override fun clone() = ProjectStorageData(this)
|
||||
|
||||
override fun getPathMacroManagerForDefaults(): PathMacroManager {
|
||||
return myPathMacroManager
|
||||
protected open fun writeOptions(root: Element, versionString: String) {
|
||||
root.setAttribute(VERSION_OPTION, "4")
|
||||
}
|
||||
|
||||
override fun getStateStorageManager(): StateStorageManager {
|
||||
if (myStateStorageManager == null) {
|
||||
myStateStorageManager = createStateStorageManager()
|
||||
override fun getChangedComponentNames(newStorageData: StorageData, substitutor: PathMacroSubstitutor?): Set<String>? {
|
||||
if (version != (newStorageData as ProjectStorageData).version) {
|
||||
return null
|
||||
}
|
||||
return myStateStorageManager!!
|
||||
return super.getChangedComponentNames(newStorageData, substitutor)
|
||||
}
|
||||
|
||||
protected abstract fun createStateStorageManager(): StateStorageManager
|
||||
}
|
||||
|
||||
@@ -62,6 +62,8 @@ public abstract class ComponentStoreImpl : IComponentStore {
|
||||
private val myComponents = Collections.synchronizedMap(THashMap<String, Any>())
|
||||
private val mySettingsSavingComponents = CopyOnWriteArrayList<SettingsSavingComponent>()
|
||||
|
||||
protected open val defaultStorageChooser: StateStorageChooser<PersistentStateComponent<*>>? = null
|
||||
|
||||
override fun initComponent(component: Any, service: Boolean) {
|
||||
if (component is SettingsSavingComponent) {
|
||||
mySettingsSavingComponents.add(component)
|
||||
@@ -135,8 +137,7 @@ public abstract class ComponentStoreImpl : IComponentStore {
|
||||
CompoundRuntimeException.doThrow(errors)
|
||||
}
|
||||
|
||||
TestOnly
|
||||
override fun saveApplicationComponent(component: Any) {
|
||||
override TestOnly fun saveApplicationComponent(component: Any) {
|
||||
val externalizationSession = getStateStorageManager().startExternalization() ?: return
|
||||
|
||||
commitComponent(externalizationSession, component, null)
|
||||
@@ -247,9 +248,7 @@ public abstract class ComponentStoreImpl : IComponentStore {
|
||||
|
||||
}
|
||||
|
||||
protected open fun getProject(): Project? {
|
||||
return null
|
||||
}
|
||||
protected open fun getProject(): Project? = null
|
||||
|
||||
private fun <T> initPersistentComponent(component: PersistentStateComponent<T>, changedStorages: Set<StateStorage>?, reloadData: Boolean): String? {
|
||||
val stateSpec = StoreUtil.getStateSpec(component)
|
||||
@@ -302,9 +301,7 @@ public abstract class ComponentStoreImpl : IComponentStore {
|
||||
return name
|
||||
}
|
||||
|
||||
protected open fun getPathMacroManagerForDefaults(): PathMacroManager? {
|
||||
return null
|
||||
}
|
||||
protected open fun getPathMacroManagerForDefaults(): PathMacroManager? = null
|
||||
|
||||
protected fun <T : Any> getDefaultState(component: Any, componentName: String, stateClass: Class<T>): T? {
|
||||
val url = DecodeDefaultsUtil.getDefaults(component, componentName) ?: return null
|
||||
@@ -324,7 +321,7 @@ public abstract class ComponentStoreImpl : IComponentStore {
|
||||
|
||||
protected open fun <T> getComponentStorageSpecs(component: PersistentStateComponent<T>, stateSpec: State, operation: StateStorageOperation): Array<Storage> {
|
||||
val storages = stateSpec.storages
|
||||
if (storages.size() == 1) {
|
||||
if (storages.size() == 1 || component is StateStorageChooserEx) {
|
||||
return storages
|
||||
}
|
||||
assert(!storages.isEmpty())
|
||||
@@ -336,13 +333,9 @@ public abstract class ComponentStoreImpl : IComponentStore {
|
||||
return stateStorageChooser.selectStorages(storages, component, operation)
|
||||
}
|
||||
|
||||
val defaultStateStorageChooser = getDefaultStateStorageChooser()
|
||||
if (defaultStateStorageChooser != null) {
|
||||
return defaultStateStorageChooser.selectStorages(storages, component, operation)
|
||||
}
|
||||
|
||||
if (component is StateStorageChooserEx) {
|
||||
return storages
|
||||
val defaultChooser = defaultStorageChooser
|
||||
if (defaultChooser != null) {
|
||||
return defaultChooser.selectStorages(storages, component, operation)
|
||||
}
|
||||
|
||||
var actualStorageCount = 0
|
||||
@@ -381,13 +374,7 @@ public abstract class ComponentStoreImpl : IComponentStore {
|
||||
return sorted
|
||||
}
|
||||
|
||||
protected open fun optimizeTestLoading(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
protected open fun getDefaultStateStorageChooser(): StateStorageChooser<PersistentStateComponent<*>>? {
|
||||
return null
|
||||
}
|
||||
protected open fun optimizeTestLoading(): Boolean = false
|
||||
|
||||
override fun isReloadPossible(componentNames: Set<String>): Boolean {
|
||||
for (componentName in componentNames) {
|
||||
|
||||
@@ -25,14 +25,14 @@ import com.intellij.openapi.util.Couple
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jdom.Element
|
||||
|
||||
public class DefaultProjectStoreImpl(project: ProjectImpl, private val projectManager: ProjectManagerImpl, pathMacroManager: PathMacroManager) : ProjectStoreImpl(project, pathMacroManager) {
|
||||
class DefaultProjectStoreImpl(project: ProjectImpl, private val projectManager: ProjectManagerImpl, pathMacroManager: PathMacroManager) : ProjectStoreImpl(project, pathMacroManager) {
|
||||
fun getStateCopy(): Element? {
|
||||
val element = projectManager.getDefaultProjectRootElement()
|
||||
return element?.clone()
|
||||
}
|
||||
|
||||
protected override fun createStateStorageManager(): StateStorageManager {
|
||||
val storage = DefaultProjectStorage(this, myPathMacroManager, projectManager)
|
||||
override protected fun createStorageManager(): StateStorageManager {
|
||||
val storage = DefaultProjectStorage(this, pathMacroManager, projectManager)
|
||||
//noinspection deprecation
|
||||
return object : StateStorageManager {
|
||||
override fun addMacro(macro: String, expansion: String) = throw UnsupportedOperationException("Method addMacro not implemented in " + javaClass)
|
||||
|
||||
@@ -23,7 +23,7 @@ import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jdom.Element
|
||||
import java.util.TreeMap
|
||||
|
||||
class ModuleFileData : BaseFileConfigurableStoreImpl.BaseStorageData, OptionManager {
|
||||
class ModuleFileData : ProjectStorageData, OptionManager {
|
||||
private var options: TreeMap<String, String>? = null
|
||||
private val module: Module
|
||||
|
||||
@@ -43,11 +43,11 @@ class ModuleFileData : BaseFileConfigurableStoreImpl.BaseStorageData, OptionMana
|
||||
}
|
||||
|
||||
override fun load(rootElement: Element, pathMacroSubstitutor: PathMacroSubstitutor?, intern: Boolean) {
|
||||
super<BaseFileConfigurableStoreImpl.BaseStorageData>.load(rootElement, pathMacroSubstitutor, intern)
|
||||
super<ProjectStorageData>.load(rootElement, pathMacroSubstitutor, intern)
|
||||
|
||||
for (attribute in rootElement.getAttributes()) {
|
||||
val name = attribute.getName()
|
||||
if (name != VERSION_OPTION && !StringUtil.isEmpty(name)) {
|
||||
if (name != ProjectStorageData.VERSION_OPTION && !StringUtil.isEmpty(name)) {
|
||||
options!!.put(name, attribute.getValue())
|
||||
}
|
||||
}
|
||||
@@ -65,14 +65,12 @@ class ModuleFileData : BaseFileConfigurableStoreImpl.BaseStorageData, OptionMana
|
||||
}
|
||||
}
|
||||
// need be last for compat reasons
|
||||
super<BaseFileConfigurableStoreImpl.BaseStorageData>.writeOptions(root, versionString)
|
||||
super<ProjectStorageData>.writeOptions(root, versionString)
|
||||
|
||||
dirty = false
|
||||
}
|
||||
|
||||
override fun clone(): StorageData {
|
||||
return ModuleFileData(this)
|
||||
}
|
||||
override fun clone() = ModuleFileData(this)
|
||||
|
||||
override fun getChangedComponentNames(newStorageData: StorageData, substitutor: PathMacroSubstitutor?): Set<String>? {
|
||||
val data = newStorageData as ModuleFileData
|
||||
@@ -80,7 +78,7 @@ class ModuleFileData : BaseFileConfigurableStoreImpl.BaseStorageData, OptionMana
|
||||
return null
|
||||
}
|
||||
|
||||
return super<BaseFileConfigurableStoreImpl.BaseStorageData>.getChangedComponentNames(newStorageData, substitutor)
|
||||
return super<ProjectStorageData>.getChangedComponentNames(newStorageData, substitutor)
|
||||
}
|
||||
|
||||
override fun setOption(key: String, value: String) {
|
||||
@@ -95,7 +93,5 @@ class ModuleFileData : BaseFileConfigurableStoreImpl.BaseStorageData, OptionMana
|
||||
}
|
||||
}
|
||||
|
||||
override fun getOptionValue(key: String): String? {
|
||||
return options!!.get(key)
|
||||
}
|
||||
}
|
||||
override fun getOptionValue(key: String) = options!!.get(key)
|
||||
}
|
||||
@@ -26,5 +26,5 @@ class ModuleStoreImpl(private val myModule: Module, pathMacroManager: PathMacroM
|
||||
|
||||
override fun getMessageBus() = myModule.getMessageBus()
|
||||
|
||||
override fun createStateStorageManager() = ModuleStateStorageManager(myPathMacroManager.createTrackingSubstitutor(), myModule)
|
||||
}
|
||||
override fun createStorageManager() = ModuleStateStorageManager(pathMacroManager.createTrackingSubstitutor(), myModule)
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.impl.stores.IComponentStore
|
||||
import com.intellij.openapi.project.impl.ProjectStoreClassProvider
|
||||
|
||||
class PlatformLangProjectStoreClassProvider : ProjectStoreClassProvider {
|
||||
override fun getProjectStoreClass(isDefaultProject: Boolean): Class<out IComponentStore> {
|
||||
return if (isDefaultProject) javaClass<DefaultProjectStoreImpl>() else javaClass<ProjectWithModulesStoreImpl>()
|
||||
}
|
||||
}
|
||||
@@ -16,29 +16,14 @@
|
||||
package com.intellij.configurationStore
|
||||
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.components.impl.stores.StorageData
|
||||
import com.intellij.openapi.project.impl.ProjectImpl
|
||||
import org.jdom.Element
|
||||
|
||||
public class ProjectStateStorageManager(macroSubstitutor: TrackingPathMacroSubstitutor, protected val myProject: ProjectImpl) : StateStorageManagerImpl(macroSubstitutor, ProjectStateStorageManager.ROOT_TAG_NAME, myProject, myProject.getPicoContainer()) {
|
||||
companion object {
|
||||
protected val ROOT_TAG_NAME: String = "project"
|
||||
}
|
||||
|
||||
override fun createStorageData(fileSpec: String, filePath: String): StorageData {
|
||||
if (fileSpec == StoragePathMacros.PROJECT_FILE) {
|
||||
return createIprStorageData(filePath)
|
||||
}
|
||||
if (fileSpec == StoragePathMacros.WORKSPACE_FILE) {
|
||||
return ProjectStoreImpl.WsStorageData(ROOT_TAG_NAME, myProject)
|
||||
}
|
||||
return ProjectStoreImpl.ProjectStorageData(ROOT_TAG_NAME, myProject)
|
||||
}
|
||||
|
||||
protected fun createIprStorageData(filePath: String): StorageData = ProjectStoreImpl.IprStorageData(ROOT_TAG_NAME, myProject)
|
||||
class ProjectStateStorageManager(macroSubstitutor: TrackingPathMacroSubstitutor, private val project: ProjectImpl) : StateStorageManagerImpl(macroSubstitutor, "project", project, project.getPicoContainer()) {
|
||||
override fun createStorageData(fileSpec: String, filePath: String) = ProjectStorageData(rootTagName)
|
||||
|
||||
override fun getOldStorageSpec(component: Any, componentName: String, operation: StateStorageOperation): String? {
|
||||
val workspace = myProject.isWorkspaceComponent(component.javaClass)
|
||||
val workspace = project.isWorkspaceComponent(component.javaClass)
|
||||
var fileSpec = if (workspace) StoragePathMacros.WORKSPACE_FILE else StoragePathMacros.PROJECT_FILE
|
||||
val storage = getStateStorage(fileSpec, if (workspace) RoamingType.DISABLED else RoamingType.PER_USER)
|
||||
if (operation === StateStorageOperation.READ && storage != null && workspace && !storage.hasState(component, componentName, javaClass<Element>(), false)) {
|
||||
@@ -47,5 +32,5 @@ public class ProjectStateStorageManager(macroSubstitutor: TrackingPathMacroSubst
|
||||
return fileSpec
|
||||
}
|
||||
|
||||
override fun createStorageTopicListener() = myProject.getMessageBus().syncPublisher(StateStorage.PROJECT_STORAGE_TOPIC)
|
||||
}
|
||||
override fun createStorageTopicListener() = project.getMessageBus().syncPublisher(StateStorage.PROJECT_STORAGE_TOPIC)
|
||||
}
|
||||
@@ -15,13 +15,11 @@
|
||||
*/
|
||||
package com.intellij.configurationStore
|
||||
|
||||
import com.intellij.CommonBundle
|
||||
import com.intellij.ide.highlighter.ProjectFileType
|
||||
import com.intellij.ide.highlighter.WorkspaceFileType
|
||||
import com.intellij.notification.Notifications
|
||||
import com.intellij.notification.NotificationsManager
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.ReadAction
|
||||
import com.intellij.openapi.components.*
|
||||
@@ -29,12 +27,8 @@ import com.intellij.openapi.components.StateStorage.SaveSession
|
||||
import com.intellij.openapi.components.impl.stores.*
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.ProjectBundle
|
||||
import com.intellij.openapi.project.impl.ProjectImpl
|
||||
import com.intellij.openapi.project.impl.ProjectManagerImpl
|
||||
import com.intellij.openapi.project.impl.ProjectManagerImpl.UnableToSaveProjectNotification
|
||||
import com.intellij.openapi.ui.MessageDialogBuilder
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.util.Pair
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
@@ -43,73 +37,18 @@ import com.intellij.openapi.vfs.*
|
||||
import com.intellij.util.PathUtilRt
|
||||
import com.intellij.util.SmartList
|
||||
import com.intellij.util.lang.CompoundRuntimeException
|
||||
import com.intellij.util.messages.MessageBus
|
||||
import org.jdom.Element
|
||||
import java.io.BufferedReader
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
import java.util.ArrayList
|
||||
|
||||
public open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMacroManager: PathMacroManager) : BaseFileConfigurableStoreImpl(pathMacroManager), IProjectStore {
|
||||
private var myScheme = StorageScheme.DEFAULT
|
||||
private var myPresentableUrl: String? = null
|
||||
open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMacroManager: PathMacroManager) : BaseFileConfigurableStoreImpl(pathMacroManager), IProjectStore {
|
||||
// protected setter used in upsource
|
||||
private var scheme = StorageScheme.DEFAULT
|
||||
protected set
|
||||
|
||||
SuppressWarnings("unused") //used in upsource
|
||||
protected fun setStorageScheme(scheme: StorageScheme) {
|
||||
myScheme = scheme
|
||||
}
|
||||
|
||||
override fun checkVersion(): Boolean {
|
||||
if (originalVersion >= 0 && originalVersion < ProjectManagerImpl.CURRENT_FORMAT_VERSION) {
|
||||
val projectFile = getProjectFile()
|
||||
LOG.assertTrue(projectFile != null)
|
||||
val message = ProjectBundle.message("project.convert.old.prompt", projectFile!!.getName(), ApplicationNamesInfo.getInstance().getProductName(), projectFile.getNameWithoutExtension() + OLD_PROJECT_SUFFIX + projectFile.getExtension())
|
||||
if (Messages.showYesNoDialog(message, CommonBundle.getWarningTitle(), Messages.getWarningIcon()) != Messages.YES) return false
|
||||
|
||||
// val conversionProblems = BaseFileConfigurableStoreImpl.conversionProblemsStorage
|
||||
// if (!ContainerUtil.isEmpty(conversionProblems)) {
|
||||
// val buffer = StringBuilder()
|
||||
// buffer.append(ProjectBundle.message("project.convert.problems.detected"))
|
||||
// for (s in conversionProblems) {
|
||||
// buffer.append('\n')
|
||||
// buffer.append(s)
|
||||
// }
|
||||
// buffer.append(ProjectBundle.message("project.convert.problems.help"))
|
||||
// if (Messages.showOkCancelDialog(myProject, buffer.toString(), ProjectBundle.message("project.convert.problems.title"), ProjectBundle.message("project.convert.problems.help.button"), CommonBundle.getCloseButtonText(), Messages.getWarningIcon()) == Messages.OK) {
|
||||
// HelpManager.getInstance().invokeHelp("project.migrationProblems")
|
||||
// }
|
||||
// }
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(object : Runnable {
|
||||
override fun run() {
|
||||
try {
|
||||
val projectDir = projectFile.getParent()
|
||||
assert(projectDir != null)
|
||||
|
||||
backup(projectDir, projectFile)
|
||||
|
||||
val workspaceFile = getWorkspaceFile()
|
||||
if (workspaceFile != null) {
|
||||
backup(projectDir, workspaceFile)
|
||||
}
|
||||
}
|
||||
catch (e: IOException) {
|
||||
LOG.error(e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
throws(IOException::class)
|
||||
private fun backup(projectDir: VirtualFile, vile: VirtualFile) {
|
||||
val oldName = vile.getNameWithoutExtension() + OLD_PROJECT_SUFFIX + vile.getExtension()
|
||||
VfsUtil.saveText(projectDir.findOrCreateChildData(this, oldName), VfsUtilCore.loadText(vile))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return originalVersion <= ProjectManagerImpl.CURRENT_FORMAT_VERSION || MessageDialogBuilder.yesNo(CommonBundle.getWarningTitle(), ProjectBundle.message("project.load.new.version.warning", myProject.getName(), ApplicationNamesInfo.getInstance().getProductName())).icon(Messages.getWarningIcon()).project(myProject).`is`()
|
||||
}
|
||||
private var presentableUrl: String? = null
|
||||
|
||||
override fun getSubstitutors(): Array<TrackingPathMacroSubstitutor> {
|
||||
val substitutor = getStateStorageManager().getMacroSubstitutor()
|
||||
@@ -126,7 +65,7 @@ public open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMac
|
||||
|
||||
val file = File(filePath)
|
||||
if (isIprPath(file)) {
|
||||
myScheme = StorageScheme.DEFAULT
|
||||
scheme = StorageScheme.DEFAULT
|
||||
|
||||
stateStorageManager.addMacro(StoragePathMacros.PROJECT_FILE, filePath)
|
||||
|
||||
@@ -140,22 +79,18 @@ public open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMac
|
||||
}, ModalityState.defaultModalityState())
|
||||
}
|
||||
else {
|
||||
myScheme = StorageScheme.DIRECTORY_BASED
|
||||
scheme = StorageScheme.DIRECTORY_BASED
|
||||
|
||||
val dirStore = if (file.isDirectory())
|
||||
File(file, Project.DIRECTORY_STORE_FOLDER)
|
||||
else
|
||||
File(file.getParentFile(), Project.DIRECTORY_STORE_FOLDER)
|
||||
val dirStore = File(if (file.isDirectory()) file else file.getParentFile(), Project.DIRECTORY_STORE_FOLDER)
|
||||
stateStorageManager.addMacro(StoragePathMacros.PROJECT_FILE, File(dirStore, "misc.xml").getPath())
|
||||
|
||||
val ws = File(dirStore, "workspace.xml")
|
||||
stateStorageManager.addMacro(StoragePathMacros.WORKSPACE_FILE, ws.getPath())
|
||||
if (!ws.exists() && !file.isDirectory()) {
|
||||
useOldWsContent(filePath, ws)
|
||||
}
|
||||
|
||||
stateStorageManager.addMacro(StoragePathMacros.PROJECT_CONFIG_DIR, dirStore.getPath())
|
||||
|
||||
val workspace = File(dirStore, "workspace.xml")
|
||||
stateStorageManager.addMacro(StoragePathMacros.WORKSPACE_FILE, workspace.getPath())
|
||||
if (!workspace.exists() && !file.isDirectory()) {
|
||||
useOldWorkspaceContent(filePath, workspace)
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().invokeAndWait(object : Runnable {
|
||||
override fun run() {
|
||||
VfsUtil.markDirtyAndRefresh(false, true, true, fs.refreshAndFindFileByIoFile(dirStore))
|
||||
@@ -163,19 +98,21 @@ public open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMac
|
||||
}, ModalityState.defaultModalityState())
|
||||
}
|
||||
|
||||
myPresentableUrl = null
|
||||
presentableUrl = null
|
||||
}
|
||||
|
||||
override fun getProjectBaseDir(): VirtualFile? {
|
||||
if (myProject.isDefault()) return null
|
||||
|
||||
if (myProject.isDefault()) {
|
||||
return null
|
||||
}
|
||||
val path = getProjectBasePath() ?: return null
|
||||
|
||||
return LocalFileSystem.getInstance().findFileByPath(path)
|
||||
}
|
||||
|
||||
override fun getProjectBasePath(): String? {
|
||||
if (myProject.isDefault()) return null
|
||||
if (myProject.isDefault()) {
|
||||
return null
|
||||
}
|
||||
|
||||
val path = getProjectFilePath()
|
||||
if (!StringUtil.isEmptyOrSpaces(path)) {
|
||||
@@ -184,27 +121,15 @@ public open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMac
|
||||
|
||||
//we are not yet initialized completely ("open directory", etc)
|
||||
val storage = getStateStorageManager().getStateStorage(StoragePathMacros.PROJECT_FILE, RoamingType.PER_USER)
|
||||
if (storage !is FileBasedStorage) {
|
||||
return null
|
||||
}
|
||||
|
||||
return getBasePath(storage.getFile())
|
||||
return if (storage is FileBasedStorage) getBasePath(storage.getFile()) else null
|
||||
}
|
||||
|
||||
private fun getBasePath(file: File): String? {
|
||||
if (myScheme === StorageScheme.DEFAULT) {
|
||||
return file.getParent()
|
||||
}
|
||||
else {
|
||||
val parentFile = file.getParentFile()
|
||||
return parentFile?.getParent()
|
||||
}
|
||||
}
|
||||
private fun getBasePath(file: File) = if (scheme == StorageScheme.DEFAULT) file.getParent() else file.getParentFile()?.getParent()
|
||||
|
||||
override fun getProjectName(): String {
|
||||
if (myScheme === StorageScheme.DIRECTORY_BASED) {
|
||||
if (scheme == StorageScheme.DIRECTORY_BASED) {
|
||||
val baseDir = getProjectBaseDir()
|
||||
assert(baseDir != null) { "scheme=" + myScheme + " project file=" + getProjectFilePath() }
|
||||
assert(baseDir != null) { "scheme=$scheme project file=${getProjectFilePath()}" }
|
||||
|
||||
val ideaDir = baseDir!!.findChild(Project.DIRECTORY_STORE_FOLDER)
|
||||
if (ideaDir != null && ideaDir.isValid()) {
|
||||
@@ -244,21 +169,19 @@ public open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMac
|
||||
}
|
||||
}
|
||||
|
||||
override fun getStorageScheme(): StorageScheme {
|
||||
return myScheme
|
||||
}
|
||||
override fun getStorageScheme() = scheme
|
||||
|
||||
override fun getPresentableUrl(): String? {
|
||||
if (myProject.isDefault()) {
|
||||
return null
|
||||
}
|
||||
if (myPresentableUrl == null) {
|
||||
val url = if (myScheme === StorageScheme.DIRECTORY_BASED) getProjectBasePath() else getProjectFilePath()
|
||||
if (presentableUrl == null) {
|
||||
val url = if (scheme == StorageScheme.DIRECTORY_BASED) getProjectBasePath() else getProjectFilePath()
|
||||
if (url != null) {
|
||||
myPresentableUrl = FileUtil.toSystemDependentName(url)
|
||||
presentableUrl = FileUtil.toSystemDependentName(url)
|
||||
}
|
||||
}
|
||||
return myPresentableUrl
|
||||
return presentableUrl
|
||||
}
|
||||
|
||||
override fun getProjectFile() = if (myProject.isDefault()) null else (getProjectFileStorage() as FileBasedStorage).getVirtualFile()
|
||||
@@ -276,10 +199,10 @@ public open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMac
|
||||
}
|
||||
|
||||
override fun getWorkspaceFilePath(): String? {
|
||||
if (myProject.isDefault()) return null
|
||||
val storage = getStateStorageManager().getStateStorage(StoragePathMacros.WORKSPACE_FILE, RoamingType.DISABLED) as FileBasedStorage?
|
||||
assert(storage != null)
|
||||
return storage!!.getFilePath()
|
||||
if (myProject.isDefault()) {
|
||||
return null
|
||||
}
|
||||
return (getStateStorageManager().getStateStorage(StoragePathMacros.WORKSPACE_FILE, RoamingType.DISABLED) as FileBasedStorage?)!!.getFilePath()
|
||||
}
|
||||
|
||||
override fun loadProjectFromTemplate(defaultProject: ProjectImpl) {
|
||||
@@ -291,65 +214,7 @@ public open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMac
|
||||
}
|
||||
}
|
||||
|
||||
override fun createStateStorageManager(): StateStorageManager {
|
||||
return ProjectStateStorageManager(myPathMacroManager.createTrackingSubstitutor(), myProject)
|
||||
}
|
||||
|
||||
open class ProjectStorageData : BaseFileConfigurableStoreImpl.BaseStorageData {
|
||||
protected val myProject: Project
|
||||
|
||||
constructor(rootElementName: String, project: Project) : super(rootElementName) {
|
||||
myProject = project
|
||||
}
|
||||
|
||||
protected constructor(storageData: ProjectStorageData) : super(storageData) {
|
||||
myProject = storageData.myProject
|
||||
}
|
||||
|
||||
override fun clone(): StorageData {
|
||||
return ProjectStorageData(this)
|
||||
}
|
||||
}
|
||||
|
||||
class WsStorageData : ProjectStorageData {
|
||||
constructor(rootElementName: String, project: Project) : super(rootElementName, project) {
|
||||
}
|
||||
|
||||
private constructor(storageData: WsStorageData) : super(storageData) {
|
||||
}
|
||||
|
||||
override fun clone(): StorageData {
|
||||
return WsStorageData(this)
|
||||
}
|
||||
}
|
||||
|
||||
class IprStorageData : ProjectStorageData {
|
||||
constructor(rootElementName: String, project: Project) : super(rootElementName, project) {
|
||||
}
|
||||
|
||||
constructor(storageData: IprStorageData) : super(storageData) {
|
||||
}
|
||||
|
||||
override fun load(rootElement: Element, pathMacroSubstitutor: PathMacroSubstitutor?, intern: Boolean) {
|
||||
val v = rootElement.getAttributeValue(VERSION_OPTION)
|
||||
//noinspection AssignmentToStaticFieldFromInstanceMethod
|
||||
originalVersion = if (v != null) Integer.parseInt(v) else 0
|
||||
|
||||
if (originalVersion != ProjectManagerImpl.CURRENT_FORMAT_VERSION) {
|
||||
convert(rootElement, originalVersion)
|
||||
}
|
||||
|
||||
super.load(rootElement, pathMacroSubstitutor, intern)
|
||||
}
|
||||
|
||||
@suppress("UNUSED_PARAMETER")
|
||||
protected fun convert(root: Element, originalVersion: Int) {
|
||||
}
|
||||
|
||||
override fun clone(): StorageData {
|
||||
return IprStorageData(this)
|
||||
}
|
||||
}
|
||||
override fun createStorageManager(): StateStorageManager = ProjectStateStorageManager(pathMacroManager.createTrackingSubstitutor(), myProject)
|
||||
|
||||
override fun doSave(saveSessions: List<SaveSession>?, readonlyFiles: MutableList<Pair<SaveSession, VirtualFile>>, prevErrors: MutableList<Throwable>?): MutableList<Throwable>? {
|
||||
var errors = prevErrors
|
||||
@@ -359,15 +224,13 @@ public open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMac
|
||||
|
||||
val notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(javaClass<UnableToSaveProjectNotification>(), myProject)
|
||||
if (readonlyFiles.isEmpty()) {
|
||||
if (notifications.size() > 0) {
|
||||
for (notification in notifications) {
|
||||
notification.expire()
|
||||
}
|
||||
for (notification in notifications) {
|
||||
notification.expire()
|
||||
}
|
||||
return errors
|
||||
}
|
||||
|
||||
if (notifications.size() > 0) {
|
||||
if (!notifications.isEmpty()) {
|
||||
throw IComponentStore.SaveCancelledException()
|
||||
}
|
||||
|
||||
@@ -405,58 +268,17 @@ public open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMac
|
||||
protected open fun beforeSave(readonlyFiles: List<Pair<SaveSession, VirtualFile>>) {
|
||||
}
|
||||
|
||||
private val myStateStorageChooser = object : StateStorageChooser<PersistentStateComponent<*>> {
|
||||
override fun selectStorages(storages: Array<Storage>, component: PersistentStateComponent<*>, operation: StateStorageOperation): Array<Storage> {
|
||||
if (operation === StateStorageOperation.READ) {
|
||||
val result = SmartList<Storage>()
|
||||
for (i in storages.indices.reversed()) {
|
||||
val storage = storages[i]
|
||||
if (storage.scheme === myScheme) {
|
||||
result.add(storage)
|
||||
}
|
||||
}
|
||||
private var _defaultStorageChooser: StateStorageChooser<PersistentStateComponent<*>>? = null
|
||||
|
||||
for (storage in storages) {
|
||||
if (storage.scheme === StorageScheme.DEFAULT && !result.contains(storage)) {
|
||||
result.add(storage)
|
||||
}
|
||||
}
|
||||
|
||||
return result.toArray<Storage>(arrayOfNulls<Storage>(result.size()))
|
||||
}
|
||||
else if (operation === StateStorageOperation.WRITE) {
|
||||
val result = SmartList<Storage>()
|
||||
for (storage in storages) {
|
||||
if (storage.scheme === myScheme) {
|
||||
result.add(storage)
|
||||
}
|
||||
}
|
||||
|
||||
if (!result.isEmpty()) {
|
||||
return result.toArray<Storage>(arrayOfNulls<Storage>(result.size()))
|
||||
}
|
||||
|
||||
for (storage in storages) {
|
||||
if (storage.scheme === StorageScheme.DEFAULT) {
|
||||
result.add(storage)
|
||||
}
|
||||
}
|
||||
|
||||
return result.toArray<Storage>(arrayOfNulls<Storage>(result.size()))
|
||||
}
|
||||
else {
|
||||
return arrayOf()
|
||||
override val defaultStorageChooser: StateStorageChooser<PersistentStateComponent<*>>?
|
||||
get() {
|
||||
if (_defaultStorageChooser == null) {
|
||||
_defaultStorageChooser = DefaultStorageChooser(scheme)
|
||||
}
|
||||
return _defaultStorageChooser
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDefaultStateStorageChooser(): StateStorageChooser<PersistentStateComponent<*>>? {
|
||||
return myStateStorageChooser
|
||||
}
|
||||
|
||||
override fun getMessageBus(): MessageBus {
|
||||
return myProject.getMessageBus()
|
||||
}
|
||||
override fun getMessageBus() = myProject.getMessageBus()
|
||||
|
||||
override fun <T> getComponentStorageSpecs(component: PersistentStateComponent<T>, stateSpec: State, operation: StateStorageOperation): Array<Storage> {
|
||||
// if we create project from default, component state written not to own storage file, but to project file,
|
||||
@@ -474,10 +296,6 @@ public open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMac
|
||||
companion object {
|
||||
private val DEFAULT_STORAGE_ANNOTATION = DefaultStorageAnnotation()
|
||||
|
||||
private val OLD_PROJECT_SUFFIX = "_old."
|
||||
|
||||
private var originalVersion = -1
|
||||
|
||||
private fun isIprPath(file: File) = FileUtilRt.extensionEquals(file.getName(), ProjectFileType.DEFAULT_EXTENSION)
|
||||
|
||||
private fun composeWsPath(filePath: String): String {
|
||||
@@ -486,7 +304,7 @@ public open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMac
|
||||
return "$filePathWithoutExt${WorkspaceFileType.DOT_DEFAULT_EXTENSION}"
|
||||
}
|
||||
|
||||
private fun useOldWsContent(filePath: String, ws: File) {
|
||||
private fun useOldWorkspaceContent(filePath: String, ws: File) {
|
||||
val oldWs = File(composeWsPath(filePath))
|
||||
if (!oldWs.exists()) {
|
||||
return
|
||||
@@ -513,3 +331,46 @@ public open class ProjectStoreImpl(protected var myProject: ProjectImpl, pathMac
|
||||
private fun getFilesList(readonlyFiles: List<Pair<SaveSession, VirtualFile>>) = Array(readonlyFiles.size()) { readonlyFiles.get(it).second }
|
||||
}
|
||||
}
|
||||
|
||||
class DefaultStorageChooser(private val scheme: StorageScheme) : StateStorageChooser<PersistentStateComponent<*>> {
|
||||
override fun selectStorages(storages: Array<Storage>, component: PersistentStateComponent<*>, operation: StateStorageOperation): Array<Storage> {
|
||||
if (operation === StateStorageOperation.READ) {
|
||||
val result = SmartList<Storage>()
|
||||
for (i in storages.indices.reversed()) {
|
||||
val storage = storages[i]
|
||||
if (storage.scheme == scheme) {
|
||||
result.add(storage)
|
||||
}
|
||||
}
|
||||
|
||||
for (storage in storages) {
|
||||
if (storage.scheme == StorageScheme.DEFAULT && !result.contains(storage)) {
|
||||
result.add(storage)
|
||||
}
|
||||
}
|
||||
|
||||
return result.toTypedArray()
|
||||
}
|
||||
else if (operation == StateStorageOperation.WRITE) {
|
||||
val result = SmartList<Storage>()
|
||||
for (storage in storages) {
|
||||
if (storage.scheme == scheme) {
|
||||
result.add(storage)
|
||||
}
|
||||
}
|
||||
|
||||
if (result.isEmpty()) {
|
||||
for (storage in storages) {
|
||||
if (storage.scheme == StorageScheme.DEFAULT) {
|
||||
result.add(storage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.toTypedArray()
|
||||
}
|
||||
else {
|
||||
return emptyArray()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,16 +20,23 @@ import com.intellij.openapi.components.StateStorage
|
||||
import com.intellij.openapi.components.StateStorage.SaveSession
|
||||
import com.intellij.openapi.components.TrackingPathMacroSubstitutor
|
||||
import com.intellij.openapi.components.impl.stores.IComponentStore
|
||||
import com.intellij.openapi.components.stateStore
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.project.impl.ProjectImpl
|
||||
import com.intellij.openapi.project.impl.ProjectStoreClassProvider
|
||||
import com.intellij.openapi.util.Pair
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.util.SmartList
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
|
||||
public class ProjectWithModulesStoreImpl(project: ProjectImpl, pathMacroManager: PathMacroManager) : ProjectStoreImpl(project, pathMacroManager) {
|
||||
class PlatformLangProjectStoreClassProvider : ProjectStoreClassProvider {
|
||||
override fun getProjectStoreClass(isDefaultProject: Boolean): Class<out IComponentStore> {
|
||||
return if (isDefaultProject) javaClass<DefaultProjectStoreImpl>() else javaClass<ProjectWithModulesStoreImpl>()
|
||||
}
|
||||
}
|
||||
|
||||
class ProjectWithModulesStoreImpl(project: ProjectImpl, pathMacroManager: PathMacroManager) : ProjectStoreImpl(project, pathMacroManager) {
|
||||
override fun reinitComponent(componentName: String, changedStorages: Set<StateStorage>): Boolean {
|
||||
if (super.reinitComponent(componentName, changedStorages)) {
|
||||
return true
|
||||
@@ -37,24 +44,19 @@ public class ProjectWithModulesStoreImpl(project: ProjectImpl, pathMacroManager:
|
||||
|
||||
for (module in getPersistentModules()) {
|
||||
// we have to reinit all modules for component because we don't know affected module
|
||||
getComponentStore(module).reinitComponent(componentName, changedStorages)
|
||||
module.stateStore.reinitComponent(componentName, changedStorages)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun getComponentStore(module: Module): IComponentStore {
|
||||
return module.getPicoContainer().getComponentInstance(javaClass<IComponentStore>()) as IComponentStore
|
||||
}
|
||||
|
||||
override fun getSubstitutors(): Array<TrackingPathMacroSubstitutor> {
|
||||
val result = SmartList<TrackingPathMacroSubstitutor>()
|
||||
ContainerUtil.addIfNotNull(result, getStateStorageManager().getMacroSubstitutor())
|
||||
|
||||
for (module in getPersistentModules()) {
|
||||
ContainerUtil.addIfNotNull(result, getComponentStore(module).getStateStorageManager().getMacroSubstitutor())
|
||||
ContainerUtil.addIfNotNull(result, module.stateStore.getStateStorageManager().getMacroSubstitutor())
|
||||
}
|
||||
|
||||
return result.toArray<TrackingPathMacroSubstitutor>(arrayOfNulls<TrackingPathMacroSubstitutor>(result.size()))
|
||||
return result.toTypedArray()
|
||||
}
|
||||
|
||||
override fun isReloadPossible(componentNames: Set<String>): Boolean {
|
||||
@@ -63,7 +65,7 @@ public class ProjectWithModulesStoreImpl(project: ProjectImpl, pathMacroManager:
|
||||
}
|
||||
|
||||
for (module in getPersistentModules()) {
|
||||
if (!getComponentStore(module).isReloadPossible(componentNames)) {
|
||||
if (!module.stateStore.isReloadPossible(componentNames)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -71,16 +73,13 @@ public class ProjectWithModulesStoreImpl(project: ProjectImpl, pathMacroManager:
|
||||
return true
|
||||
}
|
||||
|
||||
protected fun getPersistentModules(): Array<Module> {
|
||||
val moduleManager = ModuleManager.getInstance(myProject)
|
||||
return if (moduleManager == null) Module.EMPTY_ARRAY else moduleManager.getModules()
|
||||
}
|
||||
private fun getPersistentModules() = ModuleManager.getInstance(myProject)?.getModules() ?: Module.EMPTY_ARRAY
|
||||
|
||||
override protected fun beforeSave(readonlyFiles: List<Pair<SaveSession, VirtualFile>>) {
|
||||
super.beforeSave(readonlyFiles)
|
||||
|
||||
for (module in getPersistentModules()) {
|
||||
getComponentStore(module).save(readonlyFiles)
|
||||
module.stateStore.save(readonlyFiles)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,14 +37,15 @@ import java.util.LinkedHashMap
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.concurrent.withLock
|
||||
import kotlin.reflect.jvm.java
|
||||
|
||||
abstract class StateStorageManagerImpl(private val myPathMacroSubstitutor: TrackingPathMacroSubstitutor, protected val rootTagName: String, parentDisposable: Disposable, private val myPicoContainer: PicoContainer) : StateStorageManager, Disposable {
|
||||
private val myMacros = LinkedHashMap<String, String>()
|
||||
private val myStorageLock = ReentrantLock()
|
||||
private val myStorages = THashMap<String, StateStorage>()
|
||||
abstract class StateStorageManagerImpl(private val pathMacroSubstitutor: TrackingPathMacroSubstitutor, protected val rootTagName: String, parentDisposable: Disposable, private val picoContainer: PicoContainer) : StateStorageManager, Disposable {
|
||||
private val macros = LinkedHashMap<String, String>()
|
||||
private val storageLock = ReentrantLock()
|
||||
private val storages = THashMap<String, StateStorage>()
|
||||
|
||||
private var myStreamProvider: StreamProvider? = null
|
||||
private var streamProvider: StreamProvider? = null
|
||||
|
||||
init {
|
||||
Disposer.register(parentDisposable, this)
|
||||
@@ -54,23 +55,17 @@ abstract class StateStorageManagerImpl(private val myPathMacroSubstitutor: Track
|
||||
private val MACRO_PATTERN = Pattern.compile("(\\$[^\\$]*\\$)")
|
||||
}
|
||||
|
||||
override fun getMacroSubstitutor(): TrackingPathMacroSubstitutor? {
|
||||
return myPathMacroSubstitutor
|
||||
override fun getStreamProvider() = streamProvider
|
||||
|
||||
override fun setStreamProvider(value: StreamProvider?) {
|
||||
streamProvider = value
|
||||
}
|
||||
|
||||
override fun getMacroSubstitutor() = pathMacroSubstitutor
|
||||
|
||||
synchronized override fun addMacro(macro: String, expansion: String) {
|
||||
var effectiveExpansion = expansion
|
||||
assert(!macro.isEmpty())
|
||||
// backward compatibility
|
||||
if (macro.charAt(0) != '$') {
|
||||
LOG.warn("Add macros instead of macro name: " + macro)
|
||||
effectiveExpansion = '$' + macro + '$'
|
||||
}
|
||||
myMacros.put(macro, effectiveExpansion)
|
||||
}
|
||||
|
||||
protected fun getMacrosValue(macro: String): String? {
|
||||
return myMacros.get(macro)
|
||||
macros.put(macro, expansion)
|
||||
}
|
||||
|
||||
override fun getStateStorage(storageSpec: Storage): StateStorage {
|
||||
@@ -78,53 +73,37 @@ abstract class StateStorageManagerImpl(private val myPathMacroSubstitutor: Track
|
||||
val storageClass = storageSpec.storageClass.java as Class<out StateStorage>
|
||||
val key = if (storageClass == javaClass<StateStorage>()) storageSpec.file else storageClass.getName()
|
||||
|
||||
myStorageLock.lock()
|
||||
try {
|
||||
var stateStorage: StateStorage? = myStorages.get(key)
|
||||
storageLock.withLock {
|
||||
var stateStorage: StateStorage? = storages.get(key)
|
||||
if (stateStorage == null) {
|
||||
stateStorage = createStateStorage(storageClass, storageSpec.file, storageSpec.roamingType, storageSpec.stateSplitter.java)
|
||||
myStorages.put(key, stateStorage)
|
||||
storages.put(key, stateStorage)
|
||||
}
|
||||
return stateStorage
|
||||
}
|
||||
finally {
|
||||
myStorageLock.unlock()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getStateStorage(fileSpec: String, roamingType: RoamingType): StateStorage? {
|
||||
myStorageLock.lock()
|
||||
try {
|
||||
var stateStorage: StateStorage? = myStorages.get(fileSpec)
|
||||
storageLock.withLock {
|
||||
var stateStorage: StateStorage? = storages.get(fileSpec)
|
||||
if (stateStorage == null) {
|
||||
stateStorage = createStateStorage(javaClass<StateStorage>(), fileSpec, roamingType, javaClass<StateSplitterEx>())
|
||||
myStorages.put(fileSpec, stateStorage)
|
||||
storages.put(fileSpec, stateStorage)
|
||||
}
|
||||
return stateStorage
|
||||
}
|
||||
finally {
|
||||
myStorageLock.unlock()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getCachedFileStateStorages(changed: Collection<String>, deleted: Collection<String>): Couple<Collection<FileBasedStorage>> {
|
||||
myStorageLock.lock()
|
||||
try {
|
||||
return Couple.of(getCachedFileStorages(changed), getCachedFileStorages(deleted))
|
||||
}
|
||||
finally {
|
||||
myStorageLock.unlock()
|
||||
}
|
||||
}
|
||||
override fun getCachedFileStateStorages(changed: Collection<String>, deleted: Collection<String>) = storageLock.withLock { Couple.of(getCachedFileStorages(changed), getCachedFileStorages(deleted)) }
|
||||
|
||||
public fun getCachedFileStorages(fileSpecs: Collection<String>): Collection<FileBasedStorage> {
|
||||
fun getCachedFileStorages(fileSpecs: Collection<String>): Collection<FileBasedStorage> {
|
||||
if (fileSpecs.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
var result: MutableList<FileBasedStorage>? = null
|
||||
for (fileSpec in fileSpecs) {
|
||||
val storage = myStorages.get(fileSpec)
|
||||
val storage = storages.get(fileSpec)
|
||||
if (storage is FileBasedStorage) {
|
||||
if (result == null) {
|
||||
result = SmartList<FileBasedStorage>()
|
||||
@@ -132,25 +111,17 @@ abstract class StateStorageManagerImpl(private val myPathMacroSubstitutor: Track
|
||||
result.add(storage)
|
||||
}
|
||||
}
|
||||
return if (result == null) emptyList<FileBasedStorage>() else result
|
||||
return result ?: emptyList<FileBasedStorage>()
|
||||
}
|
||||
|
||||
override fun getStorageFileNames(): Collection<String> {
|
||||
myStorageLock.lock()
|
||||
try {
|
||||
return myStorages.keySet()
|
||||
}
|
||||
finally {
|
||||
myStorageLock.unlock()
|
||||
}
|
||||
}
|
||||
override fun getStorageFileNames() = storageLock.withLock { storages.keySet() }
|
||||
|
||||
// overridden in upsource
|
||||
protected fun createStateStorage(storageClass: Class<out StateStorage>, fileSpec: String, roamingType: RoamingType, SuppressWarnings("deprecation") stateSplitter: Class<out StateSplitter>): StateStorage {
|
||||
if (storageClass != javaClass<StateStorage>()) {
|
||||
val key = UUID.randomUUID().toString()
|
||||
(myPicoContainer as MutablePicoContainer).registerComponentImplementation(key, storageClass)
|
||||
return myPicoContainer.getComponentInstance(key) as StateStorage
|
||||
(picoContainer as MutablePicoContainer).registerComponentImplementation(key, storageClass)
|
||||
return picoContainer.getComponentInstance(key) as StateStorage
|
||||
}
|
||||
|
||||
val filePath = expandMacros(fileSpec)
|
||||
@@ -158,7 +129,7 @@ abstract class StateStorageManagerImpl(private val myPathMacroSubstitutor: Track
|
||||
|
||||
//noinspection deprecation
|
||||
if (stateSplitter != javaClass<StateSplitter>() && stateSplitter != javaClass<StateSplitterEx>()) {
|
||||
return DirectoryBasedStorage(myPathMacroSubstitutor, file, ReflectionUtil.newInstance(stateSplitter), this, createStorageTopicListener())
|
||||
return DirectoryBasedStorage(pathMacroSubstitutor, file, ReflectionUtil.newInstance(stateSplitter), this, createStorageTopicListener())
|
||||
}
|
||||
|
||||
if (!ApplicationManager.getApplication().isHeadlessEnvironment() && PathUtilRt.getFileName(filePath).lastIndexOf('.') < 0) {
|
||||
@@ -167,7 +138,7 @@ abstract class StateStorageManagerImpl(private val myPathMacroSubstitutor: Track
|
||||
|
||||
val effectiveRoamingType = if (roamingType == RoamingType.PER_USER && fileSpec == StoragePathMacros.WORKSPACE_FILE) RoamingType.DISABLED else roamingType
|
||||
beforeFileBasedStorageCreate()
|
||||
return object : FileBasedStorage(file, fileSpec, effectiveRoamingType, getMacroSubstitutor(fileSpec), rootTagName, this@StateStorageManagerImpl, createStorageTopicListener(), myStreamProvider) {
|
||||
return object : FileBasedStorage(file, fileSpec, effectiveRoamingType, getMacroSubstitutor(fileSpec), rootTagName, this@StateStorageManagerImpl, createStorageTopicListener(), streamProvider) {
|
||||
override fun createStorageData() = this@StateStorageManagerImpl.createStorageData(myFileSpec, getFilePath())
|
||||
|
||||
override fun isUseXmlProlog() = this@StateStorageManagerImpl.isUseXmlProlog()
|
||||
@@ -175,29 +146,17 @@ abstract class StateStorageManagerImpl(private val myPathMacroSubstitutor: Track
|
||||
}
|
||||
|
||||
override fun clearStateStorage(file: String) {
|
||||
myStorageLock.lock()
|
||||
try {
|
||||
myStorages.remove(file)
|
||||
}
|
||||
finally {
|
||||
myStorageLock.unlock()
|
||||
}
|
||||
storageLock.withLock { storages.remove(file) }
|
||||
}
|
||||
|
||||
protected open fun createStorageTopicListener(): StateStorage.Listener? {
|
||||
return null
|
||||
}
|
||||
protected open fun createStorageTopicListener(): StateStorage.Listener? = null
|
||||
|
||||
protected open fun isUseXmlProlog(): Boolean = true
|
||||
|
||||
protected open fun beforeFileBasedStorageCreate() {
|
||||
}
|
||||
|
||||
override fun getStreamProvider(): StreamProvider? {
|
||||
return myStreamProvider
|
||||
}
|
||||
|
||||
protected open fun getMacroSubstitutor(fileSpec: String): TrackingPathMacroSubstitutor? = myPathMacroSubstitutor
|
||||
protected open fun getMacroSubstitutor(fileSpec: String): TrackingPathMacroSubstitutor? = pathMacroSubstitutor
|
||||
|
||||
protected abstract fun createStorageData(fileSpec: String, filePath: String): StorageData
|
||||
|
||||
@@ -205,13 +164,13 @@ abstract class StateStorageManagerImpl(private val myPathMacroSubstitutor: Track
|
||||
val matcher = MACRO_PATTERN.matcher(file)
|
||||
while (matcher.find()) {
|
||||
val m = matcher.group(1)
|
||||
if (!myMacros.containsKey(m)) {
|
||||
if (!macros.containsKey(m)) {
|
||||
throw IllegalArgumentException("Unknown macro: " + m + " in storage file spec: " + file)
|
||||
}
|
||||
}
|
||||
|
||||
var expanded = file
|
||||
for (entry in myMacros.entrySet()) {
|
||||
for (entry in macros.entrySet()) {
|
||||
expanded = StringUtil.replace(expanded, entry.getKey(), entry.getValue())
|
||||
}
|
||||
return expanded
|
||||
@@ -219,7 +178,7 @@ abstract class StateStorageManagerImpl(private val myPathMacroSubstitutor: Track
|
||||
|
||||
override fun collapseMacros(path: String): String {
|
||||
var result = path
|
||||
for (entry in myMacros.entrySet()) {
|
||||
for (entry in macros.entrySet()) {
|
||||
result = StringUtil.replace(result, entry.getValue(), entry.getKey())
|
||||
}
|
||||
return result
|
||||
@@ -296,8 +255,4 @@ abstract class StateStorageManagerImpl(private val myPathMacroSubstitutor: Track
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
|
||||
override fun setStreamProvider(streamProvider: StreamProvider?) {
|
||||
myStreamProvider = streamProvider
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -49,6 +49,6 @@ public class DefaultProjectStorage extends XmlElementStorage {
|
||||
@Override
|
||||
@NotNull
|
||||
protected StorageData createStorageData() {
|
||||
return new BaseFileConfigurableStoreImpl.BaseStorageData(myRootElementName);
|
||||
return new StorageData(myRootElementName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,16 +158,12 @@ public class ApplicationStoreTest : LightPlatformTestCase() {
|
||||
init {
|
||||
val macroSubstitutor = ApplicationPathMacroManager().createTrackingSubstitutor()
|
||||
stateStorageManager = object : StateStorageManagerImpl(macroSubstitutor, "application", this, ApplicationManager.getApplication().getPicoContainer()) {
|
||||
override fun createStorageData(fileSpec: String, filePath: String): StorageData {
|
||||
return StorageData("application")
|
||||
}
|
||||
override fun createStorageData(fileSpec: String, filePath: String) = StorageData("application")
|
||||
|
||||
override fun getOldStorageSpec(component: Any, componentName: String, operation: StateStorageOperation): String? {
|
||||
return null
|
||||
}
|
||||
override fun getOldStorageSpec(component: Any, componentName: String, operation: StateStorageOperation) = null
|
||||
|
||||
override fun getMacroSubstitutor(fileSpec: String): TrackingPathMacroSubstitutor? {
|
||||
if (fileSpec == StoragePathMacros.APP_CONFIG + "/" + PathMacrosImpl.EXT_FILE_NAME + ".xml") {
|
||||
if (fileSpec == "${StoragePathMacros.APP_CONFIG}/${PathMacrosImpl.EXT_FILE_NAME}.xml") {
|
||||
return null
|
||||
}
|
||||
return super.getMacroSubstitutor(fileSpec)
|
||||
|
||||
@@ -204,7 +204,6 @@ public class ExportSettingsAction extends AnAction implements DumbAware {
|
||||
storage.scheme() == StorageScheme.DEFAULT &&
|
||||
!StringUtil.isEmpty(storage.file()) &&
|
||||
storage.file().startsWith(StoragePathMacros.APP_CONFIG)) {
|
||||
File file = new File(storageManager.expandMacros(storage.file()));
|
||||
|
||||
File additionalExportFile = null;
|
||||
if (!StringUtil.isEmpty(stateAnnotation.additionalExportFile())) {
|
||||
@@ -219,6 +218,7 @@ public class ExportSettingsAction extends AnAction implements DumbAware {
|
||||
}
|
||||
}
|
||||
|
||||
File file = new File(storageManager.expandMacros(storage.file()));
|
||||
boolean fileExists = !onlyExisting || file.exists();
|
||||
if (fileExists || additionalExportFile != null) {
|
||||
File[] files;
|
||||
|
||||
-2
@@ -26,8 +26,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @see com.intellij.openapi.project.ex.ProjectEx#getStateStore()
|
||||
*/
|
||||
public interface IProjectStore extends IComponentStore {
|
||||
boolean checkVersion();
|
||||
|
||||
void setProjectFilePath(@NotNull String filePath);
|
||||
|
||||
@Nullable
|
||||
|
||||
+1
-6
@@ -79,8 +79,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
public class ProjectManagerImpl extends ProjectManagerEx implements PersistentStateComponent<Element>, ExportableApplicationComponent {
|
||||
private static final Logger LOG = Logger.getInstance(ProjectManagerImpl.class);
|
||||
|
||||
public static final int CURRENT_FORMAT_VERSION = 4;
|
||||
|
||||
private static final Key<List<ProjectManagerListener>> LISTENERS_IN_PROJECT_KEY = Key.create("LISTENERS_IN_PROJECT_KEY");
|
||||
private static final Key<MultiMap<StateStorage, VirtualFile>> CHANGED_FILES_KEY = Key.create("CHANGED_FILES_KEY");
|
||||
|
||||
@@ -427,13 +425,10 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
}
|
||||
}
|
||||
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
if (!application.isUnitTestMode() && !((ProjectEx)project).getStateStore().checkVersion()) {
|
||||
if (!addToOpened(project)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!addToOpened(project)) return false;
|
||||
|
||||
fireProjectOpened(project);
|
||||
DumbService.getInstance(project).queueTask(new DumbModeTask() {
|
||||
@Override
|
||||
|
||||
@@ -36,11 +36,6 @@ import java.util.Set;
|
||||
* @author peter
|
||||
*/
|
||||
public class MockProjectStore implements IProjectStore {
|
||||
@Override
|
||||
public boolean checkVersion() {
|
||||
throw new UnsupportedOperationException("Method checkVersion is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProjectFilePath(@NotNull final String filePath) {
|
||||
throw new UnsupportedOperationException("Method setProjectFilePath is not yet implemented in " + getClass().getName());
|
||||
|
||||
Reference in New Issue
Block a user