mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[workspace model] refactoring: extract API to support loading/saving module properties in custom format
This is needed to support project in Eclipse's '.classpath' format (IDEA-246236). GitOrigin-RevId: 4e5eca9a10eae9e743a49b0798d80f6fc09eafe3
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b80fd5473c
commit
d8cf763564
@@ -126,6 +126,11 @@ internal class StorageJpsConfigurationReader(private val project: Project,
|
||||
|
||||
override fun loadComponent(fileUrl: String, componentName: String, customModuleFilePath: String?): Element? {
|
||||
val filePath = JpsPathUtil.urlToPath(fileUrl)
|
||||
if (componentName == "") {
|
||||
//this is currently used for loading Eclipse project configuration from .classpath file
|
||||
val file = VirtualFileManager.getInstance().findFileByUrl(fileUrl)
|
||||
return file?.inputStream?.use { JDOMUtil.load(it) }
|
||||
}
|
||||
if (FileUtil.extensionEquals(filePath, "iml") || isExternalModuleFile(filePath)) {
|
||||
//todo fetch data from ModuleStore (https://jetbrains.team/p/wm/issues/51)
|
||||
return getCachingReader().loadComponent(fileUrl, componentName, customModuleFilePath)
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<idea-plugin>
|
||||
<extensionPoints>
|
||||
<extensionPoint name="workspaceModel.customModuleRootsSerializer"
|
||||
interface="com.intellij.workspaceModel.ide.impl.jps.serialization.CustomModuleRootsSerializer"
|
||||
dynamic="true"/>
|
||||
<extensionPoint name="workspaceModel.customModuleComponentSerializer"
|
||||
interface="com.intellij.workspaceModel.ide.impl.jps.serialization.CustomModuleComponentSerializer"
|
||||
dynamic="true"/>
|
||||
</extensionPoints>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<registryKey key="ide.new.project.model" defaultValue="true" restartRequired="true"
|
||||
description="Enable new entities-based project model (workspace model)"/>
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.workspaceModel.ide.impl.jps.serialization
|
||||
|
||||
import com.intellij.workspaceModel.storage.VirtualFileUrl
|
||||
import com.intellij.workspaceModel.storage.VirtualFileUrlManager
|
||||
import com.intellij.workspaceModel.storage.WorkspaceEntityStorageBuilder
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.ModuleEntity
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
* This extension supports loading and saving additional settings from *.iml files to workspace model.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
interface CustomModuleComponentSerializer {
|
||||
fun loadComponent(builder: WorkspaceEntityStorageBuilder,
|
||||
moduleEntity: ModuleEntity,
|
||||
reader: JpsFileContentReader,
|
||||
imlFileUrl: VirtualFileUrl,
|
||||
errorReporter: ErrorReporter,
|
||||
virtualFileManager: VirtualFileUrlManager)
|
||||
|
||||
fun saveComponent(moduleEntity: ModuleEntity, imlFileUrl: VirtualFileUrl, writer: JpsFileContentWriter)
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.workspaceModel.ide.impl.jps.serialization
|
||||
|
||||
import com.intellij.workspaceModel.ide.JpsFileEntitySource
|
||||
import com.intellij.workspaceModel.storage.*
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.ModuleEntity
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
* This extension supports loading and saving module's dependencies in custom format instead of the standard NewModuleRootManager component
|
||||
* in *.iml file.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
interface CustomModuleRootsSerializer {
|
||||
/**
|
||||
* Corresponds to value of 'classpath' module option
|
||||
*/
|
||||
val id: String
|
||||
|
||||
fun createEntitySource(imlFileUrl: VirtualFileUrl,
|
||||
internalEntitySource: JpsFileEntitySource,
|
||||
customDir: String?,
|
||||
virtualFileManager: VirtualFileUrlManager): EntitySource?
|
||||
|
||||
fun loadRoots(builder: WorkspaceEntityStorageBuilder,
|
||||
moduleEntity: ModuleEntity,
|
||||
reader: JpsFileContentReader,
|
||||
customDir: String?,
|
||||
imlFileUrl: VirtualFileUrl,
|
||||
internalModuleListSerializer: JpsModuleListSerializer?,
|
||||
errorReporter: ErrorReporter,
|
||||
virtualFileManager: VirtualFileUrlManager)
|
||||
|
||||
fun saveRoots(module: ModuleEntity,
|
||||
entities: Map<Class<out WorkspaceEntity>, List<WorkspaceEntity>>,
|
||||
writer: JpsFileContentWriter,
|
||||
customDir: String?,
|
||||
imlFileUrl: VirtualFileUrl,
|
||||
storage: WorkspaceEntityStorage)
|
||||
}
|
||||
+58
-12
@@ -59,12 +59,12 @@ internal open class ModuleImlFileEntitiesSerializer(internal val modulePath: Mod
|
||||
reader: JpsFileContentReader, errorReporter: ErrorReporter, virtualFileManager: VirtualFileUrlManager) {
|
||||
val externalStorageEnabled = externalStorageConfigurationManager?.isEnabled ?: false
|
||||
if (!externalStorageEnabled) {
|
||||
val moduleEntity = loadModuleEntity(reader, builder, virtualFileManager)
|
||||
val moduleEntity = loadModuleEntity(reader, builder, errorReporter, virtualFileManager)
|
||||
if (moduleEntity != null) createFacetSerializer().loadFacetEntities(builder, moduleEntity, reader)
|
||||
} else {
|
||||
val externalSerializer = externalModuleListSerializer?.createSerializer(internalEntitySource, fileUrl, modulePath.group) as ModuleImlFileEntitiesSerializer?
|
||||
val moduleEntity = externalSerializer?.loadModuleEntity(reader, builder, virtualFileManager)
|
||||
?: loadModuleEntity(reader, builder, virtualFileManager)
|
||||
val moduleEntity = externalSerializer?.loadModuleEntity(reader, builder, errorReporter, virtualFileManager)
|
||||
?: loadModuleEntity(reader, builder, errorReporter, virtualFileManager)
|
||||
if (moduleEntity != null) {
|
||||
createFacetSerializer().loadFacetEntities(builder, moduleEntity, reader)
|
||||
externalSerializer?.createFacetSerializer()?.loadFacetEntities(builder, moduleEntity, reader)
|
||||
@@ -74,6 +74,7 @@ internal open class ModuleImlFileEntitiesSerializer(internal val modulePath: Mod
|
||||
|
||||
private fun loadModuleEntity(reader: JpsFileContentReader,
|
||||
builder: WorkspaceEntityStorageBuilder,
|
||||
errorReporter: ErrorReporter,
|
||||
virtualFileManager: VirtualFileUrlManager): ModuleEntity? {
|
||||
if (skipLoadingIfFileDoesNotExist) {
|
||||
val fileExists = fileUrl.file?.exists() ?: false
|
||||
@@ -82,7 +83,18 @@ internal open class ModuleImlFileEntitiesSerializer(internal val modulePath: Mod
|
||||
|
||||
val moduleOptions = readModuleOptions(reader)
|
||||
val (externalSystemOptions, externalSystemId) = readExternalSystemOptions(reader, moduleOptions)
|
||||
val entitySource = createEntitySource(externalSystemId)
|
||||
|
||||
val customRootsSerializer = moduleOptions[JpsProjectLoader.CLASSPATH_ATTRIBUTE]?.let { customSerializerId ->
|
||||
val serializer = CUSTOM_ROOTS_SERIALIZER_EP.extensions().filter { it.id == customSerializerId }.findAny().orElse(null)
|
||||
if (serializer == null) {
|
||||
LOG.warn("Classpath storage provider $customSerializerId not found")
|
||||
}
|
||||
return@let serializer
|
||||
}
|
||||
|
||||
val customDir = moduleOptions[JpsProjectLoader.CLASSPATH_DIR_ATTRIBUTE]
|
||||
val entitySource = customRootsSerializer?.createEntitySource(fileUrl, internalEntitySource, customDir, virtualFileManager)
|
||||
?: createEntitySource(externalSystemId)
|
||||
val moduleEntity = builder.addModuleEntity(modulePath.moduleName, listOf(ModuleDependencyItem.ModuleSourceDependency), entitySource)
|
||||
val moduleGroup = modulePath.group
|
||||
if (moduleGroup != null) {
|
||||
@@ -102,12 +114,21 @@ internal open class ModuleImlFileEntitiesSerializer(internal val modulePath: Mod
|
||||
builder.addModuleCustomImlDataEntity(null, customModuleOptions, moduleEntity, entitySource)
|
||||
}
|
||||
|
||||
loadExternalSystemOptions(builder, moduleEntity, reader, externalSystemOptions, externalSystemId, entitySource)
|
||||
|
||||
val rootManagerElement = reader.loadComponent(fileUrl.url, MODULE_ROOT_MANAGER_COMPONENT_NAME, getBaseDirPath())?.clone()
|
||||
if (rootManagerElement != null) {
|
||||
loadRootManager(rootManagerElement, moduleEntity, builder, virtualFileManager)
|
||||
CUSTOM_MODULE_COMPONENT_SERIALIZER_EP.extensions().forEach {
|
||||
it.loadComponent(builder, moduleEntity, reader, fileUrl, errorReporter, virtualFileManager)
|
||||
}
|
||||
if (customRootsSerializer != null) {
|
||||
customRootsSerializer.loadRoots(builder, moduleEntity, reader, customDir, fileUrl, internalModuleListSerializer, errorReporter, virtualFileManager)
|
||||
}
|
||||
else {
|
||||
loadExternalSystemOptions(builder, moduleEntity, reader, externalSystemOptions, externalSystemId, entitySource)
|
||||
|
||||
val rootManagerElement = reader.loadComponent(fileUrl.url, MODULE_ROOT_MANAGER_COMPONENT_NAME, getBaseDirPath())?.clone()
|
||||
if (rootManagerElement != null) {
|
||||
loadRootManager(rootManagerElement, moduleEntity, builder, virtualFileManager)
|
||||
}
|
||||
}
|
||||
|
||||
return moduleEntity
|
||||
}
|
||||
|
||||
@@ -332,14 +353,34 @@ internal open class ModuleImlFileEntitiesSerializer(internal val modulePath: Mod
|
||||
entities: Map<Class<out WorkspaceEntity>, List<WorkspaceEntity>>,
|
||||
storage: WorkspaceEntityStorage,
|
||||
writer: JpsFileContentWriter) {
|
||||
val rootManagerElement = JDomSerializationUtil.createComponentElement(MODULE_ROOT_MANAGER_COMPONENT_NAME)
|
||||
val externalSystemOptions = module.externalSystemOptions
|
||||
val customImlData = module.customImlData
|
||||
saveModuleOptions(externalSystemOptions, module.type, customImlData, writer)
|
||||
if (customImlData?.customModuleOptions?.containsKey(JpsProjectLoader.CLASSPATH_ATTRIBUTE) == true) {
|
||||
return
|
||||
val moduleOptions = customImlData?.customModuleOptions
|
||||
val customSerializerId = moduleOptions?.get(JpsProjectLoader.CLASSPATH_ATTRIBUTE)
|
||||
if (customSerializerId != null) {
|
||||
val serializer = CUSTOM_ROOTS_SERIALIZER_EP.extensions().filter { it.id == customSerializerId }.findAny().orElse(null)
|
||||
if (serializer != null) {
|
||||
val customDir = moduleOptions[JpsProjectLoader.CLASSPATH_DIR_ATTRIBUTE]
|
||||
serializer.saveRoots(module, entities, writer, customDir, fileUrl, storage)
|
||||
}
|
||||
else {
|
||||
LOG.warn("Classpath storage provider $customSerializerId not found")
|
||||
}
|
||||
}
|
||||
else {
|
||||
saveRootManagerElement(module, customImlData, entities, writer)
|
||||
}
|
||||
CUSTOM_MODULE_COMPONENT_SERIALIZER_EP.extensions().forEach {
|
||||
it.saveComponent(module, fileUrl, writer)
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveRootManagerElement(module: ModuleEntity,
|
||||
customImlData: ModuleCustomImlDataEntity?,
|
||||
entities: Map<Class<out WorkspaceEntity>, List<WorkspaceEntity>>,
|
||||
writer: JpsFileContentWriter) {
|
||||
val rootManagerElement = JDomSerializationUtil.createComponentElement(MODULE_ROOT_MANAGER_COMPONENT_NAME)
|
||||
saveJavaSettings(module.javaSettings, rootManagerElement)
|
||||
|
||||
if (customImlData != null) {
|
||||
@@ -547,6 +588,8 @@ internal open class ModuleImlFileEntitiesSerializer(internal val modulePath: Mod
|
||||
get() = listOf(SourceRootOrderEntity::class.java)
|
||||
|
||||
companion object {
|
||||
private val LOG = logger<ModuleImlFileEntitiesSerializer>()
|
||||
|
||||
// The comparator has reversed priority. So, the last entry of this list will be printed as a first attribute in the xml tag.
|
||||
private val orderOfKnownAttributes = listOf(
|
||||
INHERIT_COMPILER_OUTPUT_ATTRIBUTE,
|
||||
@@ -559,6 +602,9 @@ internal open class ModuleImlFileEntitiesSerializer(internal val modulePath: Mod
|
||||
private val knownAttributesComparator = Comparator<Attribute> { o1, o2 ->
|
||||
orderOfKnownAttributes.indexOf(o1.name).compareTo(orderOfKnownAttributes.indexOf(o2.name))
|
||||
}.reversed()
|
||||
|
||||
private val CUSTOM_ROOTS_SERIALIZER_EP = ExtensionPointName.create<CustomModuleRootsSerializer>("com.intellij.workspaceModel.customModuleRootsSerializer")
|
||||
private val CUSTOM_MODULE_COMPONENT_SERIALIZER_EP = ExtensionPointName.create<CustomModuleComponentSerializer>("com.intellij.workspaceModel.customModuleComponentSerializer")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user