From 03f6116ad09c9a3f0bf5d0f0ed00739711dd3373 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 3 Aug 2018 23:08:39 +0200 Subject: [PATCH] IDEA-CR-35561 use POJO instead of Element --- .../com/intellij/lang/PerFileMappingState.kt | 48 +++++++++++++++++++ .../intellij/lang/PerFileMappingsBase.java | 41 +++++++++------- 2 files changed, 73 insertions(+), 16 deletions(-) create mode 100644 platform/platform-api/src/com/intellij/lang/PerFileMappingState.kt diff --git a/platform/platform-api/src/com/intellij/lang/PerFileMappingState.kt b/platform/platform-api/src/com/intellij/lang/PerFileMappingState.kt new file mode 100644 index 000000000000..01ba2b3f9def --- /dev/null +++ b/platform/platform-api/src/com/intellij/lang/PerFileMappingState.kt @@ -0,0 +1,48 @@ +// Copyright 2000-2018 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.lang + +import com.intellij.openapi.util.text.StringUtil +import org.jdom.Element +import java.util.* + +internal class PerFileMappingState(var url: String, var value: String? = null) { + companion object { + @JvmStatic + fun write(list: List, valueAttributeName: String): Element { + val element = Element("state") + for (entry in list) { + val value = entry.value + if (value == null) { + continue + } + + val entryElement = Element("file") + entryElement.setAttribute("url", entry.url) + entryElement.setAttribute(valueAttributeName, value) + element.addContent(entryElement) + } + return element + } + + @JvmStatic + fun read(element: Element, valueAttributeName: String): List { + val entries = element.getChildren("file") + if (entries.isEmpty()) { + return emptyList() + } + + val result = ArrayList() + for (child in entries) { + val url = child.getAttributeValue("url") + val value = child.getAttributeValue(valueAttributeName) + if (StringUtil.isEmpty(url) || value == null) { + continue + } + + result.add(PerFileMappingState(url!!, value)) + } + return result + } + } +} + diff --git a/platform/platform-api/src/com/intellij/lang/PerFileMappingsBase.java b/platform/platform-api/src/com/intellij/lang/PerFileMappingsBase.java index f87235162a82..aaaca1d8c5f9 100644 --- a/platform/platform-api/src/com/intellij/lang/PerFileMappingsBase.java +++ b/platform/platform-api/src/com/intellij/lang/PerFileMappingsBase.java @@ -41,8 +41,7 @@ import java.util.*; * @author gregsh */ public abstract class PerFileMappingsBase implements PersistentStateComponent, PerFileMappings, Disposable { - - private Element myDeferredState; + private List myDeferredMappings; private final Map myMappings = ContainerUtil.newHashMap(); public PerFileMappingsBase() { @@ -156,7 +155,7 @@ public abstract class PerFileMappingsBase implements PersistentStateComponent public void setMappings(@NotNull Map mappings) { Collection oldFiles; synchronized (myMappings) { - myDeferredState = null; + myDeferredMappings = null; oldFiles = ContainerUtil.newArrayList(myMappings.keySet()); myMappings.clear(); myMappings.putAll(mappings); @@ -208,9 +207,11 @@ public abstract class PerFileMappingsBase implements PersistentStateComponent @Override public Element getState() { synchronized (myMappings) { - if (myDeferredState != null) { - return myDeferredState; + if (myDeferredMappings != null) { + //noinspection deprecation + return PerFileMappingState.write(myDeferredMappings, getValueAttribute()); } + cleanup(); Element element = new Element("x"); List files = new ArrayList<>(myMappings.keySet()); @@ -225,6 +226,7 @@ public abstract class PerFileMappingsBase implements PersistentStateComponent Element child = new Element("file"); element.addContent(child); child.setAttribute("url", file == null ? "PROJECT" : file.getUrl()); + //noinspection deprecation child.setAttribute(getValueAttribute(), valueStr); } return element; @@ -236,23 +238,32 @@ public abstract class PerFileMappingsBase implements PersistentStateComponent return null; } + @SuppressWarnings("DeprecatedIsStillUsed") @NotNull + @Deprecated + // better to not override protected String getValueAttribute() { return "value"; } @Override - public void loadState(@NotNull Element state) { + public void loadState(@NotNull Element element) { + // read not under lock + @SuppressWarnings("deprecation") + List list = PerFileMappingState.read(element, getValueAttribute()); synchronized (myMappings) { - myDeferredState = state; + myDeferredMappings = list; } } private void ensureStateLoaded() { synchronized (myMappings) { - Element state = myDeferredState; - if (state == null) return; - myDeferredState = null; + List state = myDeferredMappings; + if (state == null) { + return; + } + + myDeferredMappings = null; THashMap valuesMap = new THashMap<>(); for (T value : getAvailableValues()) { String key = serialize(value); @@ -261,11 +272,9 @@ public abstract class PerFileMappingsBase implements PersistentStateComponent } } myMappings.clear(); - List files = state.getChildren("file"); - for (Element fileElement : files) { - String url = fileElement.getAttributeValue("url"); - if (url == null) continue; - String valueStr = fileElement.getAttributeValue(getValueAttribute()); + for (PerFileMappingState entry : state) { + String url = entry.getUrl(); + String valueStr = entry.getValue(); VirtualFile file = "PROJECT".equals(url) ? null : VirtualFileManager.getInstance().findFileByUrl(url); T value = valuesMap.get(valueStr); if (value == null) { @@ -282,7 +291,7 @@ public abstract class PerFileMappingsBase implements PersistentStateComponent @TestOnly public void cleanupForNextTest() { synchronized (myMappings) { - myDeferredState = null; + myDeferredMappings = null; myMappings.clear(); } }