/* * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.util.xmlb; import com.intellij.util.ThreeState; import gnu.trove.TObjectFloatHashMap; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import java.util.LinkedHashSet; public final class SmartSerializer { private LinkedHashSet<String> mySerializedAccessorNameTracker; private TObjectFloatHashMap<String> myOrderedBindings; private final SerializationFilter mySerializationFilter; public SmartSerializer(boolean trackSerializedNames, boolean useSkipEmptySerializationFilter) { mySerializedAccessorNameTracker = trackSerializedNames ? new LinkedHashSet<String>() : null; mySerializationFilter = useSkipEmptySerializationFilter ? new SkipEmptySerializationFilter() { @Override protected ThreeState accepts(@NotNull String name, @NotNull Object beanValue) { return mySerializedAccessorNameTracker != null && mySerializedAccessorNameTracker.contains(name) ? ThreeState.YES : ThreeState.UNSURE; } } : new SkipDefaultValuesSerializationFilters() { @Override public boolean accepts(@NotNull Accessor accessor, @NotNull Object bean) { if (mySerializedAccessorNameTracker != null && mySerializedAccessorNameTracker.contains(accessor.getName())) { return true; } return super.accepts(accessor, bean); } }; } public SmartSerializer() { this(true, false); } @NotNull public static SmartSerializer skipEmptySerializer() { return new SmartSerializer(true, true); } public void readExternal(@NotNull Object bean, @NotNull Element element) { if (mySerializedAccessorNameTracker != null) { mySerializedAccessorNameTracker.clear(); myOrderedBindings = null; } BeanBinding beanBinding = getBinding(bean); beanBinding.deserializeInto(bean, element, mySerializedAccessorNameTracker); if (mySerializedAccessorNameTracker != null) { myOrderedBindings = beanBinding.computeBindingWeights(mySerializedAccessorNameTracker); } } public void writeExternal(@NotNull Object bean, @NotNull Element element) { writeExternal(bean, element, true); } public void writeExternal(@NotNull Object bean, @NotNull Element element, boolean preserveCompatibility) { BeanBinding binding = getBinding(bean); if (preserveCompatibility && myOrderedBindings != null) { binding.sortBindings(myOrderedBindings); } if (preserveCompatibility || mySerializedAccessorNameTracker == null) { binding.serializeInto(bean, element, mySerializationFilter); } else { LinkedHashSet<String> oldTracker = mySerializedAccessorNameTracker; try { mySerializedAccessorNameTracker = null; binding.serializeInto(bean, element, mySerializationFilter); } finally { mySerializedAccessorNameTracker = oldTracker; } } } @NotNull private static BeanBinding getBinding(@NotNull Object bean) { return (BeanBinding)XmlSerializerImpl.serializer.getClassBinding(bean.getClass()); } }