From a3c8b568b57c0886d3fbdfd6de7823f37994e7fa Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 3 Feb 2017 14:32:03 +0100 Subject: [PATCH] =?UTF-8?q?nullInMap=20=E2=80=94=20if=20type=20is=20not-nu?= =?UTF-8?q?ll,=20set=20to=20first=20enum=20value?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../intellij/util/xmlb/PropertyAccessor.java | 25 +++++- .../util/xmlb/KotlinXmlSerializerTest.kt | 90 +++++++++++++++++++ .../intellij/util/xmlb/XmlSerializerTest.kt | 14 --- 3 files changed, 113 insertions(+), 16 deletions(-) create mode 100644 platform/util/testSrc/com/intellij/util/xmlb/KotlinXmlSerializerTest.kt diff --git a/platform/util/src/com/intellij/util/xmlb/PropertyAccessor.java b/platform/util/src/com/intellij/util/xmlb/PropertyAccessor.java index 60a7152a01ff..669249084a47 100644 --- a/platform/util/src/com/intellij/util/xmlb/PropertyAccessor.java +++ b/platform/util/src/com/intellij/util/xmlb/PropertyAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * 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. @@ -25,6 +25,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; +import static com.intellij.util.xmlb.Binding.LOG; + class PropertyAccessor implements MutableAccessor { private final String myName; private final Class myType; @@ -72,7 +74,26 @@ class PropertyAccessor implements MutableAccessor { throw new XmlSerializationException(e); } catch (InvocationTargetException e) { - throw new XmlSerializationException(e); + Throwable cause = e.getCause(); + // see KotlinXmlSerializerTest.nullInMap + if (cause instanceof IllegalArgumentException && myGenericType instanceof Class && ((Class)myGenericType).isEnum() && cause.getMessage().contains("Parameter specified as non-null is null:")) { + Object[] constants = ((Class)myGenericType).getEnumConstants(); + if (constants.length > 0) { + try { + LOG.warn("Cannot set enum value, will be set to first enum value", e); + myWriteMethod.invoke(host, constants[0]); + return; + } + catch (IllegalAccessException e1) { + throw new XmlSerializationException(e); + } + catch (InvocationTargetException e1) { + throw new XmlSerializationException(cause); + } + } + } + + throw new XmlSerializationException(cause); } } diff --git a/platform/util/testSrc/com/intellij/util/xmlb/KotlinXmlSerializerTest.kt b/platform/util/testSrc/com/intellij/util/xmlb/KotlinXmlSerializerTest.kt new file mode 100644 index 000000000000..ef624e25c4a9 --- /dev/null +++ b/platform/util/testSrc/com/intellij/util/xmlb/KotlinXmlSerializerTest.kt @@ -0,0 +1,90 @@ +/* + * 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.loadElement +import com.intellij.util.xmlb.annotations.MapAnnotation +import com.intellij.util.xmlb.annotations.Tag +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test +import java.util.* + +class KotlinXmlSerializerTest { + @Test fun internalVar() { + @Tag("bean") + class Foo { + internal var PLACES_MAP = "" + } + + val data = Foo() + data.PLACES_MAP = "new" + doSerializerTest(""" + + """, data) + } + + @Test fun nullInMap() { + @Tag("bean") + class Foo { + @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false) + var PLACES_MAP: TreeMap = TreeMap() + } + + val data = Foo() + data.PLACES_MAP.put("", PlaceSettings()) + doSerializerTest(""" + + + """, data) + + assertThat(XmlSerializer.deserialize(loadElement(""" + + """), Foo::class.java)!!.PLACES_MAP.get("")!!.IGNORE_POLICY).isEqualTo(IgnorePolicy.DEFAULT) + + assertThat(XmlSerializer.deserialize(loadElement(""" + + """), Foo::class.java)!!.PLACES_MAP.get("")!!.IGNORE_POLICY).isEqualTo(IgnorePolicy.DEFAULT) + } +} + +private enum class IgnorePolicy constructor(val text: String) { + DEFAULT("Do not ignore"), + TRIM_WHITESPACES("Trim whitespaces"), + IGNORE_WHITESPACES("Ignore whitespaces"), + IGNORE_WHITESPACES_CHUNKS("Ignore whitespaces and empty lines"), + FORMATTING("Ignore formatting"); +} + +private data class PlaceSettings(var IGNORE_POLICY: IgnorePolicy = IgnorePolicy.DEFAULT) diff --git a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt index 0f57ef7a16e9..9e1ca3e6f87e 100644 --- a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt +++ b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt @@ -61,20 +61,6 @@ internal class BeanWithProperty { } internal class XmlSerializerTest { - @Test fun internalVar() { - @Tag("bean") - class Foo { - internal var PLACES_MAP = "" - } - - val data = Foo() - data.PLACES_MAP = "new" - doSerializerTest(""" - - """, data) - } - @Test fun annotatedInternalVar() { @Tag("bean") class Foo {