mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[workspace model] IDEA-298714 Add documentation for the introduced extension points
GitOrigin-RevId: 5303d767859c4e417e83824aca48fbd1fa015063
This commit is contained in:
committed by
intellij-monorepo-bot
parent
131873fdfe
commit
26e7978aa8
+5
-5
@@ -59,7 +59,7 @@ class ModifiableFacetModelBridgeImpl(private val initialStorage: EntityStorage,
|
||||
else -> moduleSource
|
||||
}
|
||||
if (facet is FacetBridge<*>) {
|
||||
facet.addNewModuleSettings(diff, moduleEntity, source)
|
||||
facet.addToStorage(diff, moduleEntity, source)
|
||||
} else {
|
||||
val facetConfigurationXml = FacetUtil.saveFacetConfiguration(facet)?.let { JDOMUtil.write(it) }
|
||||
val underlyingEntity = facet.underlyingFacet?.let { diff.facetMapping().getEntities(it).single() as FacetEntity }
|
||||
@@ -74,7 +74,7 @@ class ModifiableFacetModelBridgeImpl(private val initialStorage: EntityStorage,
|
||||
override fun removeFacet(facet: Facet<*>?) {
|
||||
if (facet == null) return
|
||||
if (facet is FacetBridge<*>) {
|
||||
facet.removeModuleSettings(diff, moduleEntity)
|
||||
facet.removeFromStorage(diff, moduleEntity)
|
||||
} else {
|
||||
val facetEntity = diff.facetMapping().getEntities(facet).singleOrNull() as? FacetEntity ?: return
|
||||
removeFacetEntityWithSubFacets(facetEntity)
|
||||
@@ -99,7 +99,7 @@ class ModifiableFacetModelBridgeImpl(private val initialStorage: EntityStorage,
|
||||
|
||||
override fun rename(facet: Facet<*>, newName: String) {
|
||||
if (facet is FacetBridge<*>) {
|
||||
facet.renameModuleSettings(diff, moduleEntity, newName)
|
||||
facet.rename(diff, moduleEntity, newName)
|
||||
} else {
|
||||
val entity = diff.facetMapping().getEntities(facet).single() as FacetEntity
|
||||
val newEntity = diff.modifyEntity(entity) {
|
||||
@@ -113,7 +113,7 @@ class ModifiableFacetModelBridgeImpl(private val initialStorage: EntityStorage,
|
||||
|
||||
override fun getNewName(facet: Facet<*>): String {
|
||||
if (facet is FacetBridge<*>) {
|
||||
return facet.getNewModuleSettingsName(diff, moduleEntity)
|
||||
return facet.getNewName(diff, moduleEntity)
|
||||
} else {
|
||||
val entity = diff.facetMapping().getEntities(facet).single() as FacetEntity
|
||||
return entity.name
|
||||
@@ -174,7 +174,7 @@ class ModifiableFacetModelBridgeImpl(private val initialStorage: EntityStorage,
|
||||
|
||||
override fun isNewFacet(facet: Facet<*>): Boolean {
|
||||
if (facet is FacetBridge<*>) {
|
||||
return facet.isNewModuleSettings(diff, moduleEntity)
|
||||
return facet.isNew(diff, moduleEntity)
|
||||
} else {
|
||||
val entity = diff.facetMapping().getEntities(facet).singleOrNull() as FacetEntity?
|
||||
return entity != null && entity.persistentId !in initialStorage
|
||||
|
||||
+49
@@ -7,16 +7,65 @@ import com.intellij.workspaceModel.storage.WorkspaceEntity
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.ModuleEntity
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
* Originally, [com.intellij.facet.Facet] were made to support custom setting for the module, but this solution is not
|
||||
* rather flexible and thanks to the workspace model we have an opportunity to make custom entities describing additional
|
||||
* module settings. To have a sort of bridge between new approach with declaring custom module settings and [com.intellij.facet.Facet]
|
||||
* several extension points were introduced:
|
||||
* 1) [com.intellij.workspaceModel.ide.impl.jps.serialization.CustomFacetRelatedEntitySerializer] to add support custom entity
|
||||
* serialization/deserialization as facet tag.
|
||||
* 2) [WorkspaceFacetContributor] to have an option to fire different sorts of event related to the [com.intellij.facet.Facet] during
|
||||
* the changes of your custom entity this extension point should be implemented.
|
||||
*
|
||||
* If you want to use your custom module setting entity under the hood of your facet you also need to implement
|
||||
* [com.intellij.workspaceModel.ide.legacyBridge.FacetBridge] to be properly updated.
|
||||
*
|
||||
* **N.B. Most of the time you need to implement them all to have a correct support all functionality relying on Facets.**
|
||||
*
|
||||
* Particularly this extension point was introduced to fire all related to [com.intellij.facet.FacetManagerListener] events.
|
||||
* We have a universal listener [com.intellij.workspaceModel.ide.impl.legacyBridge.facet.FacetEntityChangeListener] which base
|
||||
* on changes in your entities and data calculated by this EP can fire all these events for us.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
interface WorkspaceFacetContributor<T: WorkspaceEntity> {
|
||||
/**
|
||||
* Declare class for the main entity associated with [com.intellij.facet.Facet].
|
||||
*/
|
||||
val rootEntityType: Class<T>
|
||||
|
||||
/**
|
||||
* Get the name for the associated with entity [com.intellij.facet.Facet]
|
||||
*/
|
||||
fun getFacetName(entity: T): String
|
||||
|
||||
/**
|
||||
* Method return the module to which this entity belongs
|
||||
*/
|
||||
fun getRelatedModuleEntity(entity: T): ModuleEntity
|
||||
|
||||
/**
|
||||
* Method return the entity of type declared in [rootEntityType], associated with this module if any
|
||||
*/
|
||||
fun getRootEntityByModuleEntity(moduleEntity: ModuleEntity): T?
|
||||
|
||||
/**
|
||||
* Method for creating [com.intellij.facet.Facet] from the given entity of root type
|
||||
*/
|
||||
fun createFacetFromEntity(entity: T, project: Project): Facet<*>
|
||||
|
||||
/**
|
||||
* This field should be overridden if root entity can have children which changes can affect e.g. facet configuration
|
||||
* otherwise [com.intellij.facet.FacetManagerListener.facetConfigurationChanged] will not be fired correctly. In the same time
|
||||
* [getRootEntityByChild] should be implemented
|
||||
*/
|
||||
val childEntityTypes: List<Class<out WorkspaceEntity>>
|
||||
get() = emptyList()
|
||||
|
||||
/**
|
||||
* Method for getting entity of root type by child.
|
||||
*
|
||||
* **This method should be overridden only if the root entity have children([childEntityTypes] returns not null list), otherwise it shouldn't be touched.**
|
||||
*/
|
||||
fun getRootEntityByChild(childEntity: WorkspaceEntity): T {
|
||||
error("Implementation of the method should be overridden because root entity contains children")
|
||||
}
|
||||
|
||||
+42
-5
@@ -5,13 +5,50 @@ import com.intellij.workspaceModel.storage.MutableEntityStorage
|
||||
import com.intellij.workspaceModel.storage.WorkspaceEntity
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.ModuleEntity
|
||||
|
||||
/**
|
||||
* Bridge interface for facet which uses custom module settings entity under the hood
|
||||
*/
|
||||
interface FacetBridge<T: WorkspaceEntity> {
|
||||
fun isNewModuleSettings(mutableStorage: MutableEntityStorage, moduleEntity: ModuleEntity): Boolean
|
||||
fun getNewModuleSettingsName(mutableStorage: MutableEntityStorage, moduleEntity: ModuleEntity): String
|
||||
fun addNewModuleSettings(mutableStorage: MutableEntityStorage, moduleEntity: ModuleEntity, entitySource: EntitySource)
|
||||
fun removeModuleSettings(mutableStorage: MutableEntityStorage, moduleEntity: ModuleEntity)
|
||||
fun renameModuleSettings(mutableStorage: MutableEntityStorage, moduleEntity: ModuleEntity, newName: String)
|
||||
/**
|
||||
* Check if it's a newly created facet bridge, and it's root entity doesn't exist in main storage
|
||||
*/
|
||||
fun isNew(mutableStorage: MutableEntityStorage, moduleEntity: ModuleEntity): Boolean
|
||||
|
||||
/**
|
||||
* Returns the new name associated with given facet bridge
|
||||
*/
|
||||
fun getNewName(mutableStorage: MutableEntityStorage, moduleEntity: ModuleEntity): String
|
||||
|
||||
/**
|
||||
* Add root entity which [FacetBridge] uses under the hood, into the storage
|
||||
* @param mutableStorage for saving root entity and it's children in it
|
||||
* @param moduleEntity corresponds to this [FacetBridge]
|
||||
* @param entitySource which should be used for such entities
|
||||
*/
|
||||
fun addToStorage(mutableStorage: MutableEntityStorage, moduleEntity: ModuleEntity, entitySource: EntitySource)
|
||||
|
||||
/**
|
||||
* Removes all associated with this bridge entities from the storage
|
||||
*/
|
||||
fun removeFromStorage(mutableStorage: MutableEntityStorage, moduleEntity: ModuleEntity)
|
||||
|
||||
/**
|
||||
* Rename entity associated with this bridge
|
||||
*/
|
||||
fun rename(mutableStorage: MutableEntityStorage, moduleEntity: ModuleEntity, newName: String)
|
||||
|
||||
/**
|
||||
* Apply changes from the entity which used under the hood into the builder passed as a parameter
|
||||
*/
|
||||
fun applyChangesToStorage(mutableStorage: MutableEntityStorage, module: ModuleBridge)
|
||||
|
||||
/**
|
||||
* Update facet configuration base on the data from the related entity
|
||||
*/
|
||||
fun updateFacetConfiguration(rootEntity: T)
|
||||
|
||||
/**
|
||||
* Method returns the entity which is used under the hood of this [FacetBridge]
|
||||
*/
|
||||
fun getRootEntity(): T
|
||||
}
|
||||
+41
-2
@@ -11,16 +11,55 @@ import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.jps.model.serialization.facet.FacetState
|
||||
|
||||
/**
|
||||
* The goal of this extension point is supporting serialization/deserialization of custom entities
|
||||
* related to the module and located at the same .iml file
|
||||
* Originally, [com.intellij.facet.Facet] were made to support custom setting for the module, but this solution is not
|
||||
* rather flexible and thanks to the workspace model we have an opportunity to make custom entities describing additional
|
||||
* module settings. To have a sort of bridge between new approach with declaring custom module settings and [com.intellij.facet.Facet]
|
||||
* several extension points were introduced:
|
||||
* 1) [CustomFacetRelatedEntitySerializer] to add support custom entity
|
||||
* serialization/deserialization as facet tag.
|
||||
* 2) [com.intellij.workspaceModel.ide.legacyBridge.WorkspaceFacetContributor] to have an option to fire different sorts of event related to the [com.intellij.facet.Facet] during
|
||||
* the changes of your custom entity this extension point should be implemented.
|
||||
*
|
||||
* If you want to use your custom module setting entity under the hood of your facet you also need to implement
|
||||
* [com.intellij.workspaceModel.ide.legacyBridge.FacetBridge] to be properly updated.
|
||||
*
|
||||
* **N.B. Most of the time you need to implement them all to have a correct support all functionality relying on Facets.**
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
interface CustomFacetRelatedEntitySerializer<T: WorkspaceEntity> {
|
||||
/**
|
||||
* Declare class for the main entity associated with [com.intellij.facet.Facet].
|
||||
*/
|
||||
val rootEntityType: Class<T>
|
||||
|
||||
/**
|
||||
* Facet type this extension point can serialization/deserialization. The result of deserialization, entities of the type declared
|
||||
* at [rootEntityType] in the [com.intellij.workspaceModel.storage.EntitySource]
|
||||
*/
|
||||
val supportedFacetType: String
|
||||
|
||||
/**
|
||||
* Method for deserialization [org.jetbrains.jps.model.serialization.facet.FacetState] read from external source. Facet state is
|
||||
* an intermediate representation to avoid core communication with tags directly.
|
||||
* @param builder storage to add read from facet state entities
|
||||
* @param moduleEntity module to which these settings belong
|
||||
* @param facetState intermediate representation of facet related data read out from external sources
|
||||
* @param evaluateExternalSystemIdAndEntitySource function which should be invoked to get [com.intellij.workspaceModel.storage.EntitySource]
|
||||
* for your entities and externalSystemId which should be stored somewhere in your entities
|
||||
*/
|
||||
fun loadEntitiesFromFacetState(builder: MutableEntityStorage, moduleEntity: ModuleEntity, facetState: FacetState,
|
||||
evaluateExternalSystemIdAndEntitySource: (FacetState) -> Pair<String?, EntitySource>)
|
||||
|
||||
/**
|
||||
* Create intermediate representation from entities of declared at [rootEntityType] type which will be used for serialization on disk.
|
||||
* @param entities list of certain type entities
|
||||
* @param storeExternally indicator which tells where this data will be store, under `.idea` or in external system folder
|
||||
*/
|
||||
fun createFacetStateFromEntities(entities: List<T>, storeExternally: Boolean): List<FacetState>
|
||||
|
||||
/**
|
||||
* Method for creation facet XML tag from root type entity passed as a parameter
|
||||
*/
|
||||
fun serializeIntoXml(entity: T): Element
|
||||
|
||||
companion object {
|
||||
|
||||
-1
@@ -10,7 +10,6 @@ import com.intellij.workspaceModel.storage.bridgeEntities.addFacetEntity
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.*
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.jps.model.serialization.facet.FacetState
|
||||
import java.util.function.Consumer
|
||||
|
||||
class DefaultFacetEntitySerializer: CustomFacetRelatedEntitySerializer<FacetEntity> {
|
||||
override val rootEntityType: Class<FacetEntity>
|
||||
|
||||
Reference in New Issue
Block a user