IDEA-CR-35561 use POJO instead of Element

This commit is contained in:
Vladimir Krivosheev
2018-08-03 23:08:39 +02:00
parent 06a5bccc02
commit 03f6116ad0
2 changed files with 73 additions and 16 deletions
@@ -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<PerFileMappingState>, 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<PerFileMappingState> {
val entries = element.getChildren("file")
if (entries.isEmpty()) {
return emptyList()
}
val result = ArrayList<PerFileMappingState>()
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
}
}
}
@@ -41,8 +41,7 @@ import java.util.*;
* @author gregsh
*/
public abstract class PerFileMappingsBase<T> implements PersistentStateComponent<Element>, PerFileMappings<T>, Disposable {
private Element myDeferredState;
private List<PerFileMappingState> myDeferredMappings;
private final Map<VirtualFile, T> myMappings = ContainerUtil.newHashMap();
public PerFileMappingsBase() {
@@ -156,7 +155,7 @@ public abstract class PerFileMappingsBase<T> implements PersistentStateComponent
public void setMappings(@NotNull Map<VirtualFile, T> mappings) {
Collection<VirtualFile> 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<T> 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<VirtualFile> files = new ArrayList<>(myMappings.keySet());
@@ -225,6 +226,7 @@ public abstract class PerFileMappingsBase<T> 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<T> 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<PerFileMappingState> 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<PerFileMappingState> state = myDeferredMappings;
if (state == null) {
return;
}
myDeferredMappings = null;
THashMap<String, T> valuesMap = new THashMap<>();
for (T value : getAvailableValues()) {
String key = serialize(value);
@@ -261,11 +272,9 @@ public abstract class PerFileMappingsBase<T> implements PersistentStateComponent
}
}
myMappings.clear();
List<Element> 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<T> implements PersistentStateComponent
@TestOnly
public void cleanupForNextTest() {
synchronized (myMappings) {
myDeferredState = null;
myDeferredMappings = null;
myMappings.clear();
}
}