diff --git a/java/idea-ui/testSrc/com/intellij/facet/FacetManagerTest.java b/java/idea-ui/testSrc/com/intellij/facet/FacetManagerTest.java index 060774cc54e4..f20c61588b69 100644 --- a/java/idea-ui/testSrc/com/intellij/facet/FacetManagerTest.java +++ b/java/idea-ui/testSrc/com/intellij/facet/FacetManagerTest.java @@ -104,6 +104,19 @@ public class FacetManagerTest extends FacetTestCase { commit(model); assertNull(getFacetManager().getFacetByType(MockFacetType.ID)); } + + public void testChangeFacetConfiguration() { + String configData = "data"; + ModifiableFacetModel model = getFacetManager().createModifiableModel(); + MockFacet mockFacet = new MockFacet(myModule, "mock"); + model.addFacet(mockFacet); + mockFacet.getConfiguration().setData(configData); + commit(model); + + MockFacet facetByType = getFacetManager().getFacetByType(MockFacetType.ID); + assertEquals(configData, facetByType.getConfiguration().getData()); + assertSame(mockFacet, facetByType); + } public void testAddRemoveFacetWithSubFacet() { assertNull(getFacetManager().getFacetByType(MockSubFacetType.ID)); diff --git a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/legacyBridge/facet/ModifiableFacetModelBridge.kt b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/legacyBridge/facet/ModifiableFacetModelBridge.kt index 8ae3e688fd4a..f51ea052189c 100644 --- a/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/legacyBridge/facet/ModifiableFacetModelBridge.kt +++ b/platform/workspaceModel/ide/src/com/intellij/workspaceModel/ide/impl/legacyBridge/facet/ModifiableFacetModelBridge.kt @@ -98,6 +98,7 @@ internal class ModifiableFacetModelBridge(private val initialStorage: WorkspaceE override fun commit() { val moduleDiff = moduleBridge.diff + updateFacetConfiguration() if (moduleDiff != null) { val res = moduleDiff.addDiff(diff) populateModel(res) @@ -110,6 +111,19 @@ internal class ModifiableFacetModelBridge(private val initialStorage: WorkspaceE } } + // In some cases configuration for newly added facets changes before the actual commit e.g. MavenProjectImportHandler#configureFacet. + private fun updateFacetConfiguration() { + entityToFacet.forEach { (facetEntity, facet) -> + if (initialStorage.resolve(facetEntity.persistentId()) != null) return@forEach + val newFacetConfiguration = FacetUtil.saveFacetConfiguration(facet)?.let { JDOMUtil.write(it) } + if (facetEntity.configurationXmlTag == newFacetConfiguration) return@forEach + val newEntity = diff.modifyEntity(ModifiableFacetEntity::class.java, facetEntity) { + this.configurationXmlTag = newFacetConfiguration + } + entityToFacet.inverse()[facet] = newEntity + } + } + private fun populateModel(replaceMap: Map) { val mapInNewStore: HashBiMap> = HashBiMap.create() entityToFacet.forEach { (key, value) -> mapInNewStore[replaceMap.getOrDefault(key, key) as FacetEntity] = value } diff --git a/platform/workspaceModel/ide/tests/testSrc/com/intellij/workspaceModel/ide/FacetModelBridgeTest.kt b/platform/workspaceModel/ide/tests/testSrc/com/intellij/workspaceModel/ide/FacetModelBridgeTest.kt new file mode 100644 index 000000000000..61299ac291a6 --- /dev/null +++ b/platform/workspaceModel/ide/tests/testSrc/com/intellij/workspaceModel/ide/FacetModelBridgeTest.kt @@ -0,0 +1,90 @@ +// 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 + +import com.intellij.facet.FacetManager +import com.intellij.facet.FacetType +import com.intellij.facet.impl.FacetUtil +import com.intellij.facet.mock.MockFacet +import com.intellij.facet.mock.MockFacetType +import com.intellij.openapi.application.runWriteActionAndWait +import com.intellij.openapi.command.WriteCommandAction +import com.intellij.openapi.module.EmptyModuleType +import com.intellij.openapi.module.Module +import com.intellij.openapi.module.ModuleManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.JDOMUtil +import com.intellij.testFramework.ApplicationRule +import com.intellij.testFramework.DisposableRule +import com.intellij.testFramework.TemporaryDirectory +import com.intellij.workspaceModel.ide.impl.legacyBridge.facet.ModifiableFacetModelBridge +import com.intellij.workspaceModel.ide.legacyBridge.ModuleBridge +import com.intellij.workspaceModel.storage.bridgeEntities.FacetEntity +import org.junit.Assert +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import java.io.File + +class FacetModelBridgeTest { + @Rule + @JvmField + var application = ApplicationRule() + + @Rule + @JvmField + var temporaryDirectoryRule = TemporaryDirectory() + + @Rule + @JvmField + var disposableRule = DisposableRule() + + private lateinit var project: Project + private lateinit var module: Module + + @Before + fun prepareProject() { + project = createEmptyTestProject(temporaryDirectoryRule, disposableRule) + module = createModule() + FacetType.EP_NAME.point.registerExtension(MockFacetType(), module) + } + + @Test + fun `test changed facet config saved correctly`() = WriteCommandAction.runWriteCommandAction(project) { + val facetData = "mock" + val facet = MockFacet(module, facetData) + getFacetManager().createModifiableModel().let { modifiableModel -> + modifiableModel.addFacet(facet) + Assert.assertTrue(facet.configuration.data.isEmpty()) + facet.configuration.data = facetData + modifiableModel.commit() + } + val facetConfigXml = FacetUtil.saveFacetConfiguration(facet)?.let { JDOMUtil.write(it) } + + val facetByType = getFacetManager().getFacetByType(MockFacetType.ID) + assertNotNull(facetByType) + assertEquals(facetData, facetByType!!.configuration.data) + + val entityStorage = WorkspaceModel.getInstance(project).entityStorage + val facetEntity = entityStorage.current.entities(FacetEntity::class.java).first() + assertEquals(facetConfigXml, facetEntity.configurationXmlTag) + + getFacetManager().createModifiableModel().let { modifiableModel -> + modifiableModel as ModifiableFacetModelBridge + assertEquals(facetConfigXml, modifiableModel.getEntity(facet)!!.configurationXmlTag) + } + } + + private fun createModule(): Module = runWriteActionAndWait { + ModuleManager.getInstance(project).modifiableModel.let { moduleModel -> + val module = moduleModel.newModule(File(project.basePath, "test.iml").path, EmptyModuleType.getInstance().id) as ModuleBridge + moduleModel.commit() + module + } + } + + private fun getFacetManager(): FacetManager { + return FacetManager.getInstance(module) + } +} \ No newline at end of file