mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
we cache binding/accessors in soft reference cache map, so, SmartSerializer must not hold references to Binding
This commit is contained in:
@@ -26,7 +26,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.xmlb.annotations.*;
|
||||
import gnu.trove.TObjectDoubleHashMap;
|
||||
import gnu.trove.TObjectFloatHashMap;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -85,12 +85,7 @@ class BeanBinding extends Binding {
|
||||
|
||||
@Nullable
|
||||
public Element serializeInto(@NotNull Object o, @Nullable Element element, @NotNull SerializationFilter filter) {
|
||||
return serializeInto(o, element, filter, myBindings);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Element serializeInto(@NotNull Object o, @Nullable Element element, @NotNull SerializationFilter filter, @Nullable Binding[] bindings) {
|
||||
for (Binding binding : bindings == null ? myBindings : bindings) {
|
||||
for (Binding binding : myBindings) {
|
||||
Accessor accessor = binding.getAccessor();
|
||||
if (!filter.accepts(accessor, o)) {
|
||||
continue;
|
||||
@@ -128,10 +123,10 @@ class BeanBinding extends Binding {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Binding[] computeOrderedBindings(@NotNull LinkedHashSet<String> accessorNameTracker) {
|
||||
final TObjectDoubleHashMap<String> weights = new TObjectDoubleHashMap<String>(accessorNameTracker.size());
|
||||
double weight = 0;
|
||||
double step = (double)myBindings.length / (double)accessorNameTracker.size();
|
||||
public TObjectFloatHashMap<String> computeBindingWeights(@NotNull LinkedHashSet<String> accessorNameTracker) {
|
||||
TObjectFloatHashMap<String> weights = new TObjectFloatHashMap<String>(accessorNameTracker.size());
|
||||
float weight = 0;
|
||||
float step = (float)myBindings.length / (float)accessorNameTracker.size();
|
||||
for (String name : accessorNameTracker) {
|
||||
weights.put(name, weight);
|
||||
weight += step;
|
||||
@@ -146,19 +141,20 @@ class BeanBinding extends Binding {
|
||||
|
||||
weight++;
|
||||
}
|
||||
return weights;
|
||||
}
|
||||
|
||||
Binding[] result = Arrays.copyOf(myBindings, myBindings.length);
|
||||
Arrays.sort(result, new Comparator<Binding>() {
|
||||
public void sortBindings(@NotNull final TObjectFloatHashMap<String> weights) {
|
||||
Arrays.sort(myBindings, new Comparator<Binding>() {
|
||||
@Override
|
||||
public int compare(@NotNull Binding o1, @NotNull Binding o2) {
|
||||
String n1 = o1.getAccessor().getName();
|
||||
String n2 = o2.getAccessor().getName();
|
||||
double w1 = weights.get(n1);
|
||||
double w2 = weights.get(n2);
|
||||
float w1 = weights.get(n1);
|
||||
float w2 = weights.get(n2);
|
||||
return (int)(w1 - w2);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public void deserializeInto(@NotNull Object result, @NotNull Element element, @Nullable Set<String> accessorNameTracker) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.util.xmlb;
|
||||
|
||||
import com.intellij.util.ThreeState;
|
||||
import gnu.trove.TObjectFloatHashMap;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -24,7 +25,7 @@ import java.util.LinkedHashSet;
|
||||
|
||||
public final class SmartSerializer {
|
||||
private final LinkedHashSet<String> mySerializedAccessorNameTracker;
|
||||
private Binding[] myOrderedBindings;
|
||||
private TObjectFloatHashMap<String> myOrderedBindings;
|
||||
private final SerializationFilter mySerializationFilter;
|
||||
|
||||
public SmartSerializer(boolean trackSerializedNames, boolean useSkipEmptySerializationFilter) {
|
||||
@@ -58,15 +59,24 @@ public final class SmartSerializer {
|
||||
myOrderedBindings = null;
|
||||
}
|
||||
|
||||
BeanBinding beanBinding = (BeanBinding)XmlSerializerImpl.getBinding(bean.getClass());
|
||||
BeanBinding beanBinding = getBinding(bean);
|
||||
beanBinding.deserializeInto(bean, element, mySerializedAccessorNameTracker);
|
||||
|
||||
if (mySerializedAccessorNameTracker != null) {
|
||||
myOrderedBindings = beanBinding.computeOrderedBindings(mySerializedAccessorNameTracker);
|
||||
myOrderedBindings = beanBinding.computeBindingWeights(mySerializedAccessorNameTracker);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeExternal(@NotNull Object bean, @NotNull Element element) {
|
||||
((BeanBinding)XmlSerializerImpl.getBinding(bean.getClass())).serializeInto(bean, element, mySerializationFilter, myOrderedBindings);
|
||||
BeanBinding binding = getBinding(bean);
|
||||
if (myOrderedBindings != null) {
|
||||
binding.sortBindings(myOrderedBindings);
|
||||
}
|
||||
binding.serializeInto(bean, element, mySerializationFilter);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static BeanBinding getBinding(@NotNull Object bean) {
|
||||
return (BeanBinding)XmlSerializerImpl.getBinding(bean.getClass());
|
||||
}
|
||||
}
|
||||
@@ -1236,12 +1236,13 @@ public class XmlSerializerTest extends TestCase {
|
||||
Bean2 bean = new Bean2();
|
||||
bean.module = "module";
|
||||
bean.ab = "ab";
|
||||
doSerializerTest("<Bean2 ab=\"ab\" module=\"module\" />", bean);
|
||||
doSerializerTest("<Bean2 ab=\"ab\" module=\"module\" />", bean, new SkipDefaultValuesSerializationFilters());
|
||||
|
||||
checkSmartSerialization(new Bean2(), "<Bean2 module=\"1\" ab=\"2\" ac=\"32\" />");
|
||||
checkSmartSerialization(new Bean2(), "<Bean2 ab=\"2\" module=\"1\" ac=\"32\" />");
|
||||
checkSmartSerialization(new Bean2(), "<Bean2 ac=\"2\" module=\"1\" ab=\"32\" />");
|
||||
checkSmartSerialization(new Bean2(), "<Bean2 ac=\"2\" ab=\"32\" />");
|
||||
checkSmartSerialization(new Bean2(), "<Bean2 ac=\"2\" ab=\"32\" module=\"\" />");
|
||||
}
|
||||
|
||||
private static void checkSmartSerialization(@NotNull Bean2 bean, @NotNull String serialized) throws IOException, JDOMException {
|
||||
|
||||
Reference in New Issue
Block a user