XmlSerializer - extract common part (not related to XML) to package `com.intellij...
authorVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Wed, 8 May 2019 06:57:25 +0000 (08:57 +0200)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Wed, 8 May 2019 08:05:43 +0000 (11:05 +0300)
GitOrigin-RevId: 5cea9f854e9a024741a4abb102a0310535254217

42 files changed:
java/java-impl/src/com/intellij/internal/statistic/libraryJar/LibraryJarStatisticsService.java
platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
platform/configuration-store-impl/testSrc/xml/XmlSerializerTest.kt
platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadAssistant.java
platform/lang-impl/src/com/intellij/codeInsight/CodeInsightSettings.java
platform/lang-impl/src/com/intellij/codeInspection/naming/AbstractNamingConventionInspection.java
platform/platform-impl/src/com/intellij/ide/actions/project/loadSaveModuleRenameMapping.kt
platform/platform-resources/src/brokenPlugins.txt
platform/projectModel-api/src/com/intellij/configurationStore/KotlinAwareBeanBinding.kt
platform/projectModel-api/src/com/intellij/configurationStore/xmlSerializer.kt
platform/projectModel-api/src/com/intellij/openapi/components/BaseState.kt
platform/tasks-platform-impl/src/com/intellij/tasks/impl/TaskManagerImpl.java
platform/util/src/com/intellij/util/serialization/FieldAccessor.java [moved from platform/util/src/com/intellij/util/xmlb/FieldAccessor.java with 79% similarity]
platform/util/src/com/intellij/util/serialization/MutableAccessor.java [new file with mode: 0644]
platform/util/src/com/intellij/util/serialization/PropertyAccessor.java [moved from platform/util/src/com/intellij/util/xmlb/PropertyAccessor.java with 76% similarity]
platform/util/src/com/intellij/util/serialization/PropertyCollector.java [new file with mode: 0644]
platform/util/src/com/intellij/util/serialization/SerializationException.java [new file with mode: 0644]
platform/util/src/com/intellij/util/xmlb/AbstractCollectionBinding.java
platform/util/src/com/intellij/util/xmlb/Accessor.java
platform/util/src/com/intellij/util/xmlb/AccessorBindingWrapper.java
platform/util/src/com/intellij/util/xmlb/ArrayBinding.java
platform/util/src/com/intellij/util/xmlb/AttributeBinding.java
platform/util/src/com/intellij/util/xmlb/BasePrimitiveBinding.java
platform/util/src/com/intellij/util/xmlb/BeanBinding.java
platform/util/src/com/intellij/util/xmlb/Binding.java
platform/util/src/com/intellij/util/xmlb/CollectionBinding.java
platform/util/src/com/intellij/util/xmlb/CompactCollectionBinding.java
platform/util/src/com/intellij/util/xmlb/JDOMElementBinding.java
platform/util/src/com/intellij/util/xmlb/MapBinding.java
platform/util/src/com/intellij/util/xmlb/MutableAccessor.java [deleted file]
platform/util/src/com/intellij/util/xmlb/NotNullDeserializeBinding.java
platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java
platform/util/src/com/intellij/util/xmlb/Serializer.java
platform/util/src/com/intellij/util/xmlb/TagBinding.java
platform/util/src/com/intellij/util/xmlb/TextBinding.java
platform/util/src/com/intellij/util/xmlb/XmlSerializationException.java
platform/util/src/com/intellij/util/xmlb/XmlSerializer.java
platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java
platform/util/src/com/intellij/util/xmlb/XmlSerializerUtil.java
plugins/devkit/devkit-core/src/actions/MigrateModuleNamesInSourcesAction.kt
plugins/devkit/devkit-core/src/actions/ShowSerializedXmlAction.java

index 75ddc4ce89058bad26778ca9055b6d2aa16b3ca7..fc533afb8631456a2c832e8327ece239488a9574 100644 (file)
@@ -1,30 +1,12 @@
-/*
- * 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.
- */
+// Copyright 2000-2019 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.internal.statistic.libraryJar;
 
 import com.intellij.facet.frameworks.LibrariesDownloadConnectionService;
 import com.intellij.internal.statistic.utils.StatisticsUploadAssistant;
-import com.intellij.openapi.application.Application;
-import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.startup.StartupActivity;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.net.HttpConfigurable;
-import com.intellij.util.xmlb.XmlSerializationException;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.xmlb.XmlSerializer;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -67,7 +49,7 @@ public class LibraryJarStatisticsService implements DumbAware {
     try {
       libraryJarDescriptors = XmlSerializer.deserialize(url, LibraryJarDescriptors.class);
     }
-    catch (XmlSerializationException e) {
+    catch (SerializationException ignored) {
       //
     }
     return libraryJarDescriptors;
index 6f82beff340429ddf09d7f62bf78e5b6a5e4c724..4d8526bd784894fb4026c53ee403d3ba8aa7e25b 100644 (file)
@@ -18,8 +18,8 @@ import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
 import com.intellij.util.ResourceUtil;
 import com.intellij.util.ThreeState;
 import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.xmlb.SerializationFilter;
-import com.intellij.util.xmlb.XmlSerializationException;
 import com.intellij.util.xmlb.annotations.Property;
 import gnu.trove.THashSet;
 import gnu.trove.TObjectHashingStrategy;
@@ -307,7 +307,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool {
       try {
         XmlSerializer.deserializeInto(node, this);
       }
-      catch (XmlSerializationException e) {
+      catch (SerializationException e) {
         throw new InvalidDataException(e);
       }
     }
index 249861906651b29cfc769e372ed4bddcefe0b7b9..08499c4eb5d4d39ee838387cca55d4ea07cbf300 100644 (file)
@@ -1,4 +1,4 @@
-// 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.
+// Copyright 2000-2019 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.
 @file:Suppress("PropertyName")
 
 package com.intellij.configurationStore.xml
@@ -12,7 +12,11 @@ import com.intellij.openapi.util.text.StringUtil
 import com.intellij.testFramework.UsefulTestCase
 import com.intellij.testFramework.assertConcurrent
 import com.intellij.testFramework.assertions.Assertions.assertThat
-import com.intellij.util.xmlb.*
+import com.intellij.util.serialization.SerializationException
+import com.intellij.util.xmlb.Accessor
+import com.intellij.util.xmlb.SerializationFilter
+import com.intellij.util.xmlb.SkipDefaultsSerializationFilter
+import com.intellij.util.xmlb.XmlSerializer
 import com.intellij.util.xmlb.annotations.*
 import junit.framework.TestCase
 import org.intellij.lang.annotations.Language
@@ -326,7 +330,7 @@ internal class XmlSerializerTest {
     try {
       testSerializer("<BeanWithPropertyWithoutTagOnPrimitiveValue><name>hello</name></BeanWithPropertyWithoutTagOnPrimitiveValue>", bean)
     }
-    catch (e: XmlSerializationException) {
+    catch (e: SerializationException) {
       return
     }
 
index 541fa4552f349f197bae6f7450ece18103b5df0d..753e7fe48b98a262cbad21a5af22afd8a884fcc5 100644 (file)
@@ -35,9 +35,9 @@ import com.intellij.util.execution.ParametersListUtil;
 import com.intellij.util.graph.*;
 import com.intellij.util.io.URLUtil;
 import com.intellij.util.lang.UrlClassLoader;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.text.VersionComparatorUtil;
 import com.intellij.util.xmlb.JDOMXIncluder;
-import com.intellij.util.xmlb.XmlSerializationException;
 import gnu.trove.THashMap;
 import gnu.trove.THashSet;
 import gnu.trove.TObjectIntHashMap;
@@ -688,7 +688,7 @@ public class PluginManagerCore {
       descriptor.loadFromFile(descriptorFile, loadingContext.getXmlFactory());
       return descriptor;
     }
-    catch (XmlSerializationException | JDOMException | IOException e) {
+    catch (SerializationException | JDOMException | IOException e) {
       if (loadingContext.isEssential) ExceptionUtil.rethrow(e);
       getLogger().warn("Cannot load " + descriptorFile, e);
       prepareLoadingPluginsErrorMessage(Collections.singletonList("File '" + file.getName() + "' contains invalid plugin descriptor."));
@@ -721,7 +721,7 @@ public class PluginManagerCore {
         return descriptor;
       }
     }
-    catch (XmlSerializationException | InvalidDataException e) {
+    catch (SerializationException | InvalidDataException e) {
       if (context.isEssential) ExceptionUtil.rethrow(e);
       getLogger().info("Cannot load " + file + "!/META-INF/" + fileName, e);
       prepareLoadingPluginsErrorMessage(Collections.singletonList("File '" + file.getName() + "' contains invalid plugin descriptor."));
index 3b280ab37a875bb8811e786b5ff4aa23e06d2e22..c8ef4e1d0d53bdc8c8cef84de563d5032a315084 100644 (file)
@@ -1,3 +1,4 @@
+// Copyright 2000-2019 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.facet.frameworks;
 
 import com.intellij.facet.frameworks.beans.Artifact;
@@ -8,9 +9,8 @@ import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.containers.ContainerUtil;
-import java.util.HashSet;
 import com.intellij.util.net.HttpConfigurable;
-import com.intellij.util.xmlb.XmlSerializationException;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.xmlb.XmlSerializer;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -19,6 +19,7 @@ import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -93,7 +94,7 @@ public class LibrariesDownloadAssistant {
     try {
       allArtifacts = XmlSerializer.deserialize(url, Artifacts.class);
     }
-    catch (XmlSerializationException e) {
+    catch (SerializationException e) {
       final Throwable cause = e.getCause();
       if (!(cause instanceof IOException)) {
         LOG.error(e);
index c53f0072828ed9659eaf7080453b7626a1227583..ac070941139b0b7c9173969942af9f016427b2ec 100644 (file)
@@ -16,7 +16,7 @@ import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.registry.Registry;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.ReflectionUtil;
-import com.intellij.util.xmlb.XmlSerializationException;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.xmlb.annotations.OptionTag;
 import com.intellij.util.xmlb.annotations.Property;
 import com.intellij.util.xmlb.annotations.Transient;
@@ -198,7 +198,7 @@ public class CodeInsightSettings implements PersistentStateComponent<Element>, C
     try {
       XmlSerializer.deserializeInto(state, this);
     }
-    catch (XmlSerializationException e) {
+    catch (SerializationException e) {
       LOG.info(e);
     }
   }
@@ -231,7 +231,7 @@ public class CodeInsightSettings implements PersistentStateComponent<Element>, C
     try {
       XmlSerializer.serializeObjectInto(this, element);
     }
-    catch (XmlSerializationException e) {
+    catch (SerializationException e) {
       LOG.info(e);
     }
   }
index 56f814508dbd6f799363a58ce5f7604a76f88f21..f0644167b015579f0d25987f184805cd3b3e8d45 100644 (file)
@@ -1,6 +1,4 @@
-// Copyright 2000-2017 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.
+// Copyright 2000-2019 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.codeInspection.naming;
 
 import com.intellij.codeInspection.LocalInspectionTool;
@@ -15,9 +13,9 @@ import com.intellij.ui.CheckBoxList;
 import com.intellij.ui.CheckBoxListListener;
 import com.intellij.ui.components.JBScrollPane;
 import com.intellij.util.ObjectUtils;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.ui.JBUI;
 import com.intellij.util.ui.UIUtil;
-import com.intellij.util.xmlb.XmlSerializationException;
 import com.intellij.util.xmlb.XmlSerializer;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
@@ -25,8 +23,8 @@ import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.awt.*;
-import java.util.*;
 import java.util.List;
+import java.util.*;
 import java.util.function.Consumer;
 
 /**
@@ -98,7 +96,7 @@ public abstract class AbstractNamingConventionInspection<T extends PsiNameIdenti
         XmlSerializer.deserializeInto(conventionBean, extension);
         conventionBean.initPattern();
       }
-      catch (XmlSerializationException e) {
+      catch (SerializationException e) {
         throw new InvalidDataException(e);
       }
       String enabled = extension.getAttributeValue("enabled");
index e2fc4c80be4e3358deaa07cda34d5f838806f62a..cc2fa466792bfa939a01abf8aa25b2167a2a9506 100644 (file)
@@ -1,4 +1,4 @@
-// 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.
+// Copyright 2000-2019 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.ide.actions.project
 
 import com.intellij.CommonBundle
@@ -18,9 +18,9 @@ import com.intellij.openapi.util.JDOMUtil
 import com.intellij.openapi.util.io.FileUtil
 import com.intellij.openapi.vfs.LocalFileSystem
 import com.intellij.openapi.wm.IdeFocusManager
+import com.intellij.util.serialization.SerializationException
 import com.intellij.util.ui.UIUtil
 import com.intellij.util.write
-import com.intellij.util.xmlb.XmlSerializationException
 import com.intellij.util.xmlb.XmlSerializer
 import java.awt.event.ActionEvent
 import javax.swing.AbstractAction
@@ -44,7 +44,7 @@ class LoadModuleRenamingSchemeAction(private val dialog: ConvertModuleGroupsToQu
     val renamingState = try {
       XmlSerializer.deserialize(JDOMUtil.load(file.inputStream), ModuleRenamingHistoryState::class.java)
     }
-    catch (e: XmlSerializationException) {
+    catch (e: SerializationException) {
       LOG.info(e)
       showError(e.message ?: "unknown error")
       return
index 4cc58934aceeea66ecf86c201f459d6440f3a309..01066e809f5954993a8658a4829a99e151e5770f 100644 (file)
@@ -117,4 +117,5 @@ com.undo_software.clion.reverse 2.0.0
 "Randori Compiler" 0.2.0 0.2.1 0.2.3 0.2.4 0.3.0
 Docker 173.2605 191.4212.41 191.4738.6
 "Log Support" 1.0.11-11_and_newer
-"Changes Bar" 1.1 1.2.2 1.2.3 1.3 1.3.1 1.4 1.5 1.6 1.6.1 1.6.2 1.6.3
\ No newline at end of file
+"Changes Bar" 1.1 1.2.2 1.2.3 1.3 1.3.1 1.4 1.5 1.6 1.6.1 1.6.2 1.6.3
+uk.co.reecedunn.intellij.plugin.xquery 1.4 1.4.1
\ No newline at end of file
index 2f88aa76c08cc50ddc3ae2bcfdfa55363ec29cdc..c6a5d7abae931e240ba8f233cfeca04d57ce7f5e 100644 (file)
@@ -5,9 +5,9 @@ import com.intellij.openapi.components.BaseState
 import com.intellij.openapi.diagnostic.logger
 import com.intellij.util.ObjectUtils
 import com.intellij.util.containers.IntArrayList
+import com.intellij.util.serialization.MutableAccessor
+import com.intellij.util.serialization.PropertyAccessor
 import com.intellij.util.xmlb.BeanBinding
-import com.intellij.util.xmlb.MutableAccessor
-import com.intellij.util.xmlb.PropertyAccessor
 import com.intellij.util.xmlb.SerializationFilter
 import org.jdom.Element
 import java.lang.reflect.Constructor
index 975b1854d87ac41f083db3558d5790975e2da7d3..03c034486ea9bb1a1bdc90df7136a904f04197c4 100644 (file)
@@ -7,6 +7,8 @@ import com.intellij.openapi.components.PersistentStateComponent
 import com.intellij.openapi.util.JDOMUtil
 import com.intellij.reference.SoftReference
 import com.intellij.util.io.URLUtil
+import com.intellij.util.serialization.MutableAccessor
+import com.intellij.util.serialization.SerializationException
 import com.intellij.util.xmlb.*
 import gnu.trove.THashMap
 import org.jdom.Element
@@ -53,7 +55,7 @@ fun <T : Any> T.serialize(filter: SerializationFilter? = getDefaultSerialization
       binding.serialize(this, null, filter) as Element
     }
   }
-  catch (e: XmlSerializationException) {
+  catch (e: SerializationException) {
     throw e
   }
   catch (e: Exception) {
@@ -78,7 +80,7 @@ fun <T> Element.deserialize(clazz: Class<T>): T {
   try {
     return (serializer.getClassBinding(clazz) as NotNullDeserializeBinding).deserialize(null, this) as T
   }
-  catch (e: XmlSerializationException) {
+  catch (e: SerializationException) {
     throw e
   }
   catch (e: Exception) {
@@ -105,7 +107,7 @@ fun Element.deserializeInto(bean: Any) {
   try {
     (serializer.getClassBinding(bean.javaClass) as BeanBinding).deserializeInto(bean, this)
   }
-  catch (e: XmlSerializationException) {
+  catch (e: SerializationException) {
     throw e
   }
   catch (e: Exception) {
index 2fd0b7eba6c1afe6680e0455d09564547b768432..f8b7a19bd3d21b09e1d54ed4de5f382d83382ef0 100644 (file)
@@ -4,8 +4,8 @@ package com.intellij.openapi.components
 import com.intellij.configurationStore.properties.*
 import com.intellij.openapi.diagnostic.logger
 import com.intellij.openapi.util.ModificationTracker
+import com.intellij.util.serialization.PropertyAccessor
 import com.intellij.util.xmlb.Accessor
-import com.intellij.util.xmlb.PropertyAccessor
 import com.intellij.util.xmlb.SerializationFilter
 import com.intellij.util.xmlb.annotations.Transient
 import gnu.trove.THashSet
index 4d9156dc08493d81c44dbd93e503c475973ef540..7cd7896915147a2ffffd7d5b8b7e85e671e65b17 100644 (file)
@@ -34,8 +34,8 @@ import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.Convertor;
 import com.intellij.util.containers.MultiMap;
 import com.intellij.util.io.HttpRequests;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.ui.UIUtil;
-import com.intellij.util.xmlb.XmlSerializationException;
 import com.intellij.util.xmlb.XmlSerializerUtil;
 import com.intellij.util.xmlb.annotations.Property;
 import com.intellij.util.xmlb.annotations.Tag;
@@ -635,7 +635,7 @@ public final class TaskManagerImpl extends TaskManager implements PersistentStat
           repository.initializeRepository();
           repositories.add(repository);
         }
-        catch (XmlSerializationException e) {
+        catch (SerializationException e) {
           LOG.error(e.getMessage(), e);
         }
       }
similarity index 79%
rename from platform/util/src/com/intellij/util/xmlb/FieldAccessor.java
rename to platform/util/src/com/intellij/util/serialization/FieldAccessor.java
index e14fb4e2f76beeeed840936ae6c7579f46647261..0f63accc4a7aa7c364ebee083323345b8460a22c 100644 (file)
@@ -1,7 +1,6 @@
 // Copyright 2000-2019 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.util.xmlb;
+package com.intellij.util.serialization;
 
-import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -9,7 +8,7 @@ import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.Type;
 
-class FieldAccessor implements MutableAccessor {
+final class FieldAccessor implements MutableAccessor {
   private final Field myField;
 
   FieldAccessor(@NotNull Field field) {
@@ -24,7 +23,7 @@ class FieldAccessor implements MutableAccessor {
       return myField.get(o);
     }
     catch (IllegalAccessException e) {
-      throw new XmlSerializationException("Reading " + myField, e);
+      throw new SerializationException("Reading " + myField, e);
     }
   }
 
@@ -34,7 +33,7 @@ class FieldAccessor implements MutableAccessor {
       myField.set(host, value);
     }
     catch (IllegalAccessException e) {
-      throw new XmlSerializationException("Writing " + myField, e);
+      throw new SerializationException("Writing " + myField, e);
     }
   }
 
@@ -44,7 +43,7 @@ class FieldAccessor implements MutableAccessor {
       myField.setBoolean(host, value);
     }
     catch (IllegalAccessException e) {
-      throw new XmlSerializationException("Writing " + myField, e);
+      throw new SerializationException("Writing " + myField, e);
     }
   }
 
@@ -54,7 +53,7 @@ class FieldAccessor implements MutableAccessor {
       myField.setInt(host, value);
     }
     catch (IllegalAccessException e) {
-      throw new XmlSerializationException("Writing " + myField, e);
+      throw new SerializationException("Writing " + myField, e);
     }
   }
 
@@ -64,7 +63,7 @@ class FieldAccessor implements MutableAccessor {
       myField.setShort(host, value);
     }
     catch (IllegalAccessException e) {
-      throw new XmlSerializationException("Writing " + myField, e);
+      throw new SerializationException("Writing " + myField, e);
     }
   }
 
@@ -74,7 +73,7 @@ class FieldAccessor implements MutableAccessor {
       myField.setLong(host, value);
     }
     catch (IllegalAccessException e) {
-      throw new XmlSerializationException("Writing " + myField, e);
+      throw new SerializationException("Writing " + myField, e);
     }
   }
 
@@ -84,7 +83,7 @@ class FieldAccessor implements MutableAccessor {
       myField.setFloat(host, value);
     }
     catch (IllegalAccessException e) {
-      throw new XmlSerializationException("Writing " + myField, e);
+      throw new SerializationException("Writing " + myField, e);
     }
   }
 
@@ -94,7 +93,7 @@ class FieldAccessor implements MutableAccessor {
       myField.setDouble(host, value);
     }
     catch (IllegalAccessException e) {
-      throw new XmlSerializationException("Writing " + myField, e);
+      throw new SerializationException("Writing " + myField, e);
     }
   }
 
@@ -103,6 +102,7 @@ class FieldAccessor implements MutableAccessor {
     return myField.getAnnotation(annotationClass);
   }
 
+  @NotNull
   @Override
   public String getName() {
     return myField.getName();
@@ -123,7 +123,7 @@ class FieldAccessor implements MutableAccessor {
     return myField.isAccessible();
   }
 
-  @NonNls
+  @NotNull
   public String toString() {
     return "FieldAccessor[" + myField.getDeclaringClass() + "." + myField.getName() + "]";
   }
diff --git a/platform/util/src/com/intellij/util/serialization/MutableAccessor.java b/platform/util/src/com/intellij/util/serialization/MutableAccessor.java
new file mode 100644 (file)
index 0000000..310f33c
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2000-2019 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.util.serialization;
+
+import com.intellij.util.xmlb.Accessor;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+@ApiStatus.Internal
+public interface MutableAccessor extends Accessor {
+  void set(@NotNull Object host, @Nullable Object value);
+
+  void setBoolean(@NotNull Object host, boolean value);
+
+  void setInt(@NotNull Object host, int value);
+
+  void setShort(@NotNull Object host, short value);
+
+  void setLong(@NotNull Object host, long value);
+
+  void setDouble(@NotNull Object host, double value);
+
+  void setFloat(@NotNull Object host, float value);
+}
similarity index 76%
rename from platform/util/src/com/intellij/util/xmlb/PropertyAccessor.java
rename to platform/util/src/com/intellij/util/serialization/PropertyAccessor.java
index 01bbb82d81ddc7c81882b4c9880af15281b2d6ef..a4180e7188a64cbaaf016acc65d23220dab3b01e 100644 (file)
@@ -1,31 +1,29 @@
 // Copyright 2000-2019 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.util.xmlb;
+package com.intellij.util.serialization;
 
-import com.intellij.util.ExceptionUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.ExceptionUtilRt;
+import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.beans.PropertyDescriptor;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 
-import static com.intellij.util.xmlb.Binding.LOG;
+@ApiStatus.Internal
+public final class PropertyAccessor implements MutableAccessor {
+  private static final Logger LOG = Logger.getInstance(PropertyAccessor.class);
 
-public class PropertyAccessor implements MutableAccessor {
   private final String myName;
   private final Class<?> myType;
   private final Method myReadMethod;
   private final Method myWriteMethod;
   private final Type myGenericType;
 
-  public PropertyAccessor(PropertyDescriptor descriptor) {
-    this(descriptor.getName(), descriptor.getPropertyType(), descriptor.getReadMethod(), descriptor.getWriteMethod());
-  }
-
-  public PropertyAccessor(String name, Class<?> type, @NotNull Method readMethod, @Nullable Method writeMethod) {
+  public PropertyAccessor(@NotNull String name, @NotNull Class<?> type, @NotNull Method readMethod, @Nullable Method writeMethod) {
     myName = name;
     myType = type;
     myReadMethod = readMethod;
@@ -38,7 +36,8 @@ public class PropertyAccessor implements MutableAccessor {
         myWriteMethod.setAccessible(true);
       }
     }
-    catch (SecurityException ignored) { }
+    catch (SecurityException ignored) {
+    }
   }
 
   @NotNull
@@ -52,12 +51,11 @@ public class PropertyAccessor implements MutableAccessor {
       return myReadMethod.invoke(o);
     }
     catch (IllegalAccessException e) {
-      throw new XmlSerializationException(e);
+      throw new SerializationException(e);
     }
     catch (InvocationTargetException e) {
-      Throwable exception = e.getTargetException();
-      ExceptionUtil.rethrowUnchecked(exception);
-      throw new XmlSerializationException(e);
+      ExceptionUtilRt.rethrowUnchecked(e.getTargetException());
+      throw new SerializationException(e);
     }
   }
 
@@ -67,7 +65,7 @@ public class PropertyAccessor implements MutableAccessor {
       myWriteMethod.invoke(host, value);
     }
     catch (IllegalAccessException e) {
-      throw new XmlSerializationException(e);
+      throw new SerializationException(e);
     }
     catch (InvocationTargetException e) {
       Throwable cause = e.getCause();
@@ -80,16 +78,13 @@ public class PropertyAccessor implements MutableAccessor {
             myWriteMethod.invoke(host, constants[0]);
             return;
           }
-          catch (IllegalAccessException e1) {
-            throw new XmlSerializationException(e);
-          }
-          catch (InvocationTargetException e1) {
-            throw new XmlSerializationException(cause);
+          catch (IllegalAccessException | InvocationTargetException e1) {
+            throw new SerializationException(e);
           }
         }
       }
 
-      throw new XmlSerializationException(cause);
+      throw new SerializationException(cause);
     }
   }
 
@@ -132,6 +127,7 @@ public class PropertyAccessor implements MutableAccessor {
     return annotation;
   }
 
+  @NotNull
   @Override
   public String getName() {
     return myName;
diff --git a/platform/util/src/com/intellij/util/serialization/PropertyCollector.java b/platform/util/src/com/intellij/util/serialization/PropertyCollector.java
new file mode 100644 (file)
index 0000000..c65224a
--- /dev/null
@@ -0,0 +1,208 @@
+// Copyright 2000-2019 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.util.serialization;
+
+import com.intellij.openapi.util.Couple;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.*;
+import java.lang.reflect.*;
+import java.util.List;
+import java.util.*;
+
+@ApiStatus.Internal
+public class PropertyCollector {
+  private final boolean collectAccessors;
+
+  public PropertyCollector(boolean collectAccessors) {
+    this.collectAccessors = collectAccessors;
+  }
+
+  @NotNull
+  public List<MutableAccessor> collect(@NotNull Class<?> aClass) {
+    List<MutableAccessor> accessors = new ArrayList<>();
+
+    Map<String, Couple<Method>> nameToAccessors;
+    // special case for Rectangle.class to avoid infinite recursion during serialization due to bounds() method
+    if (!collectAccessors || aClass == Rectangle.class) {
+      nameToAccessors = Collections.emptyMap();
+    }
+    else {
+      nameToAccessors = collectPropertyAccessors(aClass, accessors);
+    }
+
+    int propertyAccessorCount = accessors.size();
+    collectFieldAccessors(aClass, accessors);
+
+    // if there are field accessor and property accessor, prefer field - Kotlin generates private var and getter/setter, but annotation moved to var, not to getter/setter
+    // so, we must remove duplicated accessor
+    for (int j = propertyAccessorCount; j < accessors.size(); j++) {
+      String name = accessors.get(j).getName();
+      if (nameToAccessors.containsKey(name)) {
+        for (int i = 0; i < propertyAccessorCount; i++) {
+          if (accessors.get(i).getName().equals(name)) {
+            accessors.remove(i);
+            propertyAccessorCount--;
+            //noinspection AssignmentToForLoopParameter
+            j--;
+            break;
+          }
+        }
+      }
+    }
+
+    return accessors;
+  }
+
+  private void collectFieldAccessors(@NotNull Class<?> aClass, @NotNull List<? super MutableAccessor> accessors) {
+    Class<?> currentClass = aClass;
+    do {
+      for (Field field : currentClass.getDeclaredFields()) {
+        int modifiers = field.getModifiers();
+        if (Modifier.isStatic(modifiers) || Modifier.isTransient(modifiers)) {
+          continue;
+        }
+
+        if (!hasStoreAnnotations(field)) {
+          if (!(Modifier.isPublic(modifiers))) {
+            continue;
+          }
+
+          if (Modifier.isFinal(modifiers)) {
+            Class<?> fieldType = field.getType();
+            // we don't want to allow final fields of all types, but only supported
+            if (!(Collection.class.isAssignableFrom(fieldType) || Map.class.isAssignableFrom(fieldType))) {
+              continue;
+            }
+          }
+
+          if (isAnnotatedAsTransient(field)) {
+            continue;
+          }
+        }
+
+        accessors.add(new FieldAccessor(field));
+      }
+    }
+    while ((currentClass = currentClass.getSuperclass()) != null && !isAnnotatedAsTransient(currentClass));
+  }
+
+  @NotNull
+  private Map<String, Couple<Method>> collectPropertyAccessors(@NotNull Class<?> aClass, @NotNull List<? super MutableAccessor> accessors) {
+    // (name,(getter,setter))
+    final Map<String, Couple<Method>> candidates = new TreeMap<>();
+    for (Method method : aClass.getMethods()) {
+      if (!Modifier.isPublic(method.getModifiers())) {
+        continue;
+      }
+
+      NameAndIsSetter propertyData = getPropertyData(method.getName());
+      if (propertyData == null || propertyData.name.equals("class") ||
+          method.getParameterTypes().length != (propertyData.isSetter ? 1 : 0)) {
+        continue;
+      }
+
+      Couple<Method> candidate = candidates.get(propertyData.name);
+      if (candidate == null) {
+        candidate = Couple.getEmpty();
+      }
+      if ((propertyData.isSetter ? candidate.second : candidate.first) != null) {
+        continue;
+      }
+      candidate = new Couple<>(propertyData.isSetter ? candidate.first : method, propertyData.isSetter ? method : candidate.second);
+      candidates.put(propertyData.name, candidate);
+    }
+
+    for (Iterator<Map.Entry<String, Couple<Method>>> iterator = candidates.entrySet().iterator(); iterator.hasNext(); ) {
+      Map.Entry<String, Couple<Method>> candidate = iterator.next();
+      Couple<Method> methods = candidate.getValue();
+      Method getter = methods.first;
+      Method setter = methods.second;
+      if (isAcceptableProperty(getter, setter)) {
+        accessors.add(new PropertyAccessor(candidate.getKey(), getter.getReturnType(), getter, setter));
+      }
+      else {
+        iterator.remove();
+      }
+    }
+    return candidates;
+  }
+
+  @Nullable
+  private static NameAndIsSetter getPropertyData(@NotNull String methodName) {
+    String part = "";
+    boolean isSetter = false;
+    if (methodName.startsWith("get")) {
+      part = methodName.substring(3);
+    }
+    else if (methodName.startsWith("is")) {
+      part = methodName.substring(2);
+    }
+    else if (methodName.startsWith("set")) {
+      part = methodName.substring(3);
+      isSetter = true;
+    }
+
+    if (part.isEmpty()) {
+      return null;
+    }
+
+    int suffixIndex = part.indexOf('$');
+    if (suffixIndex > 0) {
+      // ignore special kotlin properties
+      if (part.endsWith("$annotations")) {
+        return null;
+      }
+      // see XmlSerializerTest.internalVar
+      part = part.substring(0, suffixIndex);
+    }
+    return new NameAndIsSetter(decapitalize(part), isSetter);
+  }
+
+  @NotNull
+  private static String decapitalize(@NotNull String name) {
+    if (name.isEmpty() || ((name.length() > 1) && Character.isUpperCase(name.charAt(1)) && Character.isUpperCase(name.charAt(0)))) {
+      return name;
+    }
+
+    char[] chars = name.toCharArray();
+    chars[0] = Character.toLowerCase(name.charAt(0));
+    return new String(chars);
+  }
+
+  private boolean isAcceptableProperty(@Nullable Method getter, @Nullable Method setter) {
+    if (getter == null || isAnnotatedAsTransient(getter)) {
+      return false;
+    }
+
+    if (setter == null) {
+      // check hasStoreAnnotations to ensure that this addition will not lead to regression (since there is a chance that there is some existing not-annotated list getters without setter)
+      return (Collection.class.isAssignableFrom(getter.getReturnType()) || Map.class.isAssignableFrom(getter.getReturnType())) && hasStoreAnnotations(getter);
+    }
+
+    if (isAnnotatedAsTransient(setter) || !getter.getReturnType().equals(setter.getParameterTypes()[0])) {
+      return false;
+    }
+
+    return true;
+  }
+
+  protected boolean isAnnotatedAsTransient(@NotNull AnnotatedElement element) {
+    return false;
+  }
+
+  protected boolean hasStoreAnnotations(@NotNull AccessibleObject element) {
+    return false;
+  }
+
+  private static final class NameAndIsSetter {
+    final String name;
+    final boolean isSetter;
+
+    NameAndIsSetter(String name, boolean isSetter) {
+      this.name = name;
+      this.isSetter = isSetter;
+    }
+  }
+}
\ No newline at end of file
diff --git a/platform/util/src/com/intellij/util/serialization/SerializationException.java b/platform/util/src/com/intellij/util/serialization/SerializationException.java
new file mode 100644 (file)
index 0000000..2338b9f
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2000-2019 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.util.serialization;
+
+public class SerializationException extends RuntimeException {
+  public SerializationException() {
+  }
+
+  public SerializationException(String message) {
+    super(message);
+  }
+
+  public SerializationException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  public SerializationException(Throwable cause) {
+    super(cause);
+  }
+}
index 51083021f2f17f163e266f212cbd87f365f655c5..9df3168c0138d9ec7df130eb0426ab26ebe64544 100644 (file)
@@ -6,6 +6,7 @@ import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.SmartList;
 import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.serialization.MutableAccessor;
 import com.intellij.util.xmlb.annotations.AbstractCollection;
 import com.intellij.util.xmlb.annotations.XCollection;
 import org.jdom.Content;
index c128f18d292da39ef93efe2a149d973bfddabc29..ce51f89081647fb8e1f5a65f14845905cc065c57 100644 (file)
@@ -11,6 +11,7 @@ public interface Accessor {
 
   <T extends Annotation> T getAnnotation(@NotNull Class<T> annotationClass);
 
+  @NotNull
   String getName();
 
   Class<?> getValueClass();
index f0afdbb848c58607dc667444eaf5326f57c11366..394b0e5638703e582368877c19cd95f21a7af9f9 100644 (file)
@@ -2,6 +2,7 @@
 package com.intellij.util.xmlb;
 
 import com.intellij.openapi.util.text.StringUtilRt;
+import com.intellij.util.serialization.MutableAccessor;
 import com.intellij.util.xmlb.annotations.Property;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
index 1ae0a870d2e03b90d9244f1911454b8a2992b2df..7156a8dbdfeedf000f6decedb444a9c66fb00dcd 100644 (file)
@@ -1,7 +1,8 @@
-// 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.
+// Copyright 2000-2019 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.util.xmlb;
 
 import com.intellij.util.ArrayUtil;
+import com.intellij.util.serialization.MutableAccessor;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
index 4c5e9bb7c95bd1f3e2911bd3cf0d9c567c91fba1..d6b31896ac061335d1dcf7dc6755dba791bdc134 100644 (file)
@@ -1,8 +1,7 @@
-/*
- * Copyright 2000-2017 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.
- */
+// Copyright 2000-2019 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.util.xmlb;
 
+import com.intellij.util.serialization.MutableAccessor;
 import com.intellij.util.xmlb.annotations.Attribute;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
index 7d3485625da8aeab763421c1d9a125039def6f90..a82baa56a0483601938e5759cdbd6124be26dec6 100644 (file)
@@ -1,10 +1,9 @@
-/*
- * Copyright 2000-2017 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.
- */
+// Copyright 2000-2019 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.util.xmlb;
 
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.ReflectionUtil;
+import com.intellij.util.serialization.MutableAccessor;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
index 07c10ce3116d9d39b71f7a778f69f8c7c8a50f62..26621352508e50d3e0489bd95bc0f1cd97184e36 100644 (file)
@@ -1,12 +1,13 @@
 // Copyright 2000-2019 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.util.xmlb;
 
-import com.intellij.openapi.util.Couple;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.ReflectionUtil;
 import com.intellij.util.ThreeState;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.MultiMap;
+import com.intellij.util.serialization.MutableAccessor;
+import com.intellij.util.serialization.PropertyCollector;
 import com.intellij.util.xmlb.annotations.AbstractCollection;
 import com.intellij.util.xmlb.annotations.*;
 import gnu.trove.TObjectFloatHashMap;
@@ -16,14 +17,14 @@ import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.awt.*;
-import java.beans.Introspector;
-import java.lang.reflect.*;
-import java.util.List;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Type;
 import java.util.*;
 
 public class BeanBinding extends NotNullDeserializeBinding {
   private static final Map<Class, List<MutableAccessor>> ourAccessorCache = ContainerUtil.newConcurrentMap();
+  private static final PropertyCollector PROPERTY_COLLECTOR = new XmlSerializerPropertyCollector();
 
   private final String myTagName;
   @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
@@ -289,43 +290,13 @@ public class BeanBinding extends NotNullDeserializeBinding {
       return accessors;
     }
 
-    accessors = new ArrayList<>();
-
-    Map<String, Couple<Method>> nameToAccessors;
-    // special case for Rectangle.class to avoid infinite recursion during serialization due to bounds() method
-    if (aClass == Rectangle.class) {
-      nameToAccessors = Collections.emptyMap();
-    }
-    else {
-      nameToAccessors = collectPropertyAccessors(aClass, accessors);
-    }
-
-    int propertyAccessorCount = accessors.size();
-    collectFieldAccessors(aClass, accessors);
-
-    // if there are field accessor and property accessor, prefer field - Kotlin generates private var and getter/setter, but annotation moved to var, not to getter/setter
-    // so, we must remove duplicated accessor
-    for (int j = propertyAccessorCount; j < accessors.size(); j++) {
-      String name = accessors.get(j).getName();
-      if (nameToAccessors.containsKey(name)) {
-        for (int i = 0; i < propertyAccessorCount; i++) {
-          if (accessors.get(i).getName().equals(name)) {
-            accessors.remove(i);
-            propertyAccessorCount--;
-            //noinspection AssignmentToForLoopParameter
-            j--;
-            break;
-          }
-        }
-      }
-    }
+    accessors = PROPERTY_COLLECTOR.collect(aClass);
+    ourAccessorCache.put(aClass, accessors);
 
     if (accessors.isEmpty() && !isAssertBindings(aClass)) {
       LOG.warn("no accessors for " + aClass);
     }
 
-    ourAccessorCache.put(aClass, accessors);
-
     return accessors;
   }
 
@@ -340,149 +311,30 @@ public class BeanBinding extends NotNullDeserializeBinding {
     return false;
   }
 
-  private static class NameAndIsSetter {
-    final String name;
-    final boolean isSetter;
-
-    private NameAndIsSetter(String name, boolean isSetter) {
-      this.name = name;
-      this.isSetter = isSetter;
+  private static final class XmlSerializerPropertyCollector extends PropertyCollector {
+    XmlSerializerPropertyCollector() {
+      super(/* collectAccessors = */ true);
     }
-  }
 
-  @NotNull
-  private static Map<String, Couple<Method>> collectPropertyAccessors(@NotNull Class<?> aClass, @NotNull List<? super MutableAccessor> accessors) {
-    final Map<String, Couple<Method>> candidates = new TreeMap<>(); // (name,(getter,setter))
-    for (Method method : aClass.getMethods()) {
-      if (!Modifier.isPublic(method.getModifiers())) {
-        continue;
-      }
-
-      NameAndIsSetter propertyData = getPropertyData(method.getName());
-      if (propertyData == null || propertyData.name.equals("class") ||
-          method.getParameterTypes().length != (propertyData.isSetter ? 1 : 0)) {
-        continue;
-      }
-
-      Couple<Method> candidate = candidates.get(propertyData.name);
-      if (candidate == null) {
-        candidate = Couple.getEmpty();
-      }
-      if ((propertyData.isSetter ? candidate.second : candidate.first) != null) {
-        continue;
-      }
-      candidate = Couple.of(propertyData.isSetter ? candidate.first : method, propertyData.isSetter ? method : candidate.second);
-      candidates.put(propertyData.name, candidate);
-    }
-
-    for (Iterator<Map.Entry<String, Couple<Method>>> iterator = candidates.entrySet().iterator(); iterator.hasNext(); ) {
-      Map.Entry<String, Couple<Method>> candidate = iterator.next();
-      Couple<Method> methods = candidate.getValue();
-      Method getter = methods.first;
-      Method setter = methods.second;
-      if (isAcceptableProperty(getter, setter)) {
-        accessors.add(new PropertyAccessor(candidate.getKey(), getter.getReturnType(), getter, setter));
-      }
-      else {
-        iterator.remove();
-      }
-    }
-    return candidates;
-  }
-
-  private static boolean isAcceptableProperty(@Nullable Method getter, @Nullable Method setter) {
-    if (getter == null || getter.getAnnotation(Transient.class) != null) {
-      return false;
+    @Override
+    protected boolean isAnnotatedAsTransient(@NotNull AnnotatedElement element) {
+      return element.isAnnotationPresent(Transient.class);
     }
 
-    if (setter == null) {
-      // check hasStoreAnnotations to ensure that this addition will not lead to regression (since there is a chance that there is some existing not-annotated list getters without setter)
-      return (Collection.class.isAssignableFrom(getter.getReturnType()) || Map.class.isAssignableFrom(getter.getReturnType())) && hasStoreAnnotations(getter);
-    }
-
-    if (setter.getAnnotation(Transient.class) != null || !getter.getReturnType().equals(setter.getParameterTypes()[0])) {
-      return false;
-    }
-
-    return true;
-  }
-
-  private static boolean hasStoreAnnotations(@NotNull AccessibleObject object) {
-    //noinspection deprecation
-    return object.getAnnotation(OptionTag.class) != null ||
-           object.getAnnotation(Tag.class) != null ||
-           object.getAnnotation(Attribute.class) != null ||
-           object.getAnnotation(Property.class) != null ||
-           object.getAnnotation(Text.class) != null ||
-           object.getAnnotation(CollectionBean.class) != null ||
-           object.getAnnotation(MapAnnotation.class) != null ||
-           object.getAnnotation(XMap.class) != null ||
-           object.getAnnotation(XCollection.class) != null ||
-           object.getAnnotation(AbstractCollection.class) != null;
-  }
-
-  private static void collectFieldAccessors(@NotNull Class<?> aClass, @NotNull List<? super MutableAccessor> accessors) {
-    Class<?> currentClass = aClass;
-    do {
-      for (Field field : currentClass.getDeclaredFields()) {
-        int modifiers = field.getModifiers();
-        if (Modifier.isStatic(modifiers) || Modifier.isTransient(modifiers)) {
-          continue;
-        }
-
-        if (!hasStoreAnnotations(field)) {
-          if (!(Modifier.isPublic(modifiers))) {
-            continue;
-          }
-
-          if (Modifier.isFinal(modifiers)) {
-            Class<?> fieldType = field.getType();
-            // we don't want to allow final fields of all types, but only supported
-            if (!(Collection.class.isAssignableFrom(fieldType) || Map.class.isAssignableFrom(fieldType))) {
-              continue;
-            }
-          }
-
-          if (field.getAnnotation(Transient.class) != null) {
-            continue;
-          }
-        }
-
-        accessors.add(new FieldAccessor(field));
-      }
-    }
-    while ((currentClass = currentClass.getSuperclass()) != null && currentClass.getAnnotation(Transient.class) == null);
-  }
-
-  @Nullable
-  private static NameAndIsSetter getPropertyData(@NotNull String methodName) {
-    String part = "";
-    boolean isSetter = false;
-    if (methodName.startsWith("get")) {
-      part = methodName.substring(3);
-    }
-    else if (methodName.startsWith("is")) {
-      part = methodName.substring(2);
-    }
-    else if (methodName.startsWith("set")) {
-      part = methodName.substring(3);
-      isSetter = true;
-    }
-
-    if (part.isEmpty()) {
-      return null;
-    }
-
-    int suffixIndex = part.indexOf('$');
-    if (suffixIndex > 0) {
-      // ignore special kotlin properties
-      if (part.endsWith("$annotations")) {
-        return null;
-      }
-      // see XmlSerializerTest.internalVar
-      part = part.substring(0, suffixIndex);
+    @Override
+    protected boolean hasStoreAnnotations(@NotNull AccessibleObject element) {
+      //noinspection deprecation
+      return element.isAnnotationPresent(OptionTag.class) ||
+             element.isAnnotationPresent(Tag.class) ||
+             element.isAnnotationPresent(Attribute.class) ||
+             element.isAnnotationPresent(Property.class) ||
+             element.isAnnotationPresent(Text.class) ||
+             element.isAnnotationPresent(CollectionBean.class) ||
+             element.isAnnotationPresent(MapAnnotation.class) ||
+             element.isAnnotationPresent(XMap.class) ||
+             element.isAnnotationPresent(XCollection.class) ||
+             element.isAnnotationPresent(AbstractCollection.class);
     }
-    return new NameAndIsSetter(Introspector.decapitalize(part), isSetter);
   }
 
   public String toString() {
index 2452d94b5cb10afe1d8a21d0d6db11b371527e30..5403992431e8a6ee42f2667bbea94659fa31c3b4 100644 (file)
@@ -1,7 +1,8 @@
-// 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.
+// Copyright 2000-2019 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.util.xmlb;
 
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.serialization.MutableAccessor;
 import org.jdom.Content;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
index 2e02148ac291c8f3d0b85ccced1538835c250681..d9ae1a9a6cc2054375b655e47b72fb09da12303e 100644 (file)
@@ -1,7 +1,8 @@
-// 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.
+// Copyright 2000-2019 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.util.xmlb;
 
 import com.intellij.util.SmartList;
+import com.intellij.util.serialization.MutableAccessor;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
index 1052777a4865a71a2eb5f6b72872d1cdb7b11980..db9a49fed120ed25d756a1d8a37491fc1024d07e 100644 (file)
@@ -3,6 +3,7 @@ package com.intellij.util.xmlb;
 
 import com.intellij.openapi.util.JDOMUtil;
 import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.serialization.MutableAccessor;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
index 14b55398c6b4d09d6245685813d6e0b21dfe4fc3..9ae8a43011ec3f9efd3f82c9d78cbe777b5a7fb1 100644 (file)
@@ -1,7 +1,8 @@
-// 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.
+// Copyright 2000-2019 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.util.xmlb;
 
 import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.serialization.MutableAccessor;
 import com.intellij.util.xmlb.annotations.Tag;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
index 465d9d2bcdf8b46a56fc2988c96caeef42ebc3b1..55ca4793de523090742a995935bfb32cda9660ba 100644 (file)
@@ -4,6 +4,7 @@ package com.intellij.util.xmlb;
 import com.intellij.openapi.util.JDOMUtil;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.ReflectionUtil;
+import com.intellij.util.serialization.MutableAccessor;
 import com.intellij.util.xmlb.annotations.MapAnnotation;
 import com.intellij.util.xmlb.annotations.XMap;
 import gnu.trove.THashMap;
diff --git a/platform/util/src/com/intellij/util/xmlb/MutableAccessor.java b/platform/util/src/com/intellij/util/xmlb/MutableAccessor.java
deleted file mode 100644 (file)
index e9e7497..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2000-2015 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 org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public interface MutableAccessor extends Accessor {
-  void set(@NotNull Object host, @Nullable Object value);
-
-  void setBoolean(@NotNull Object host, boolean value);
-
-  void setInt(@NotNull Object host, int value);
-
-  void setShort(@NotNull Object host, short value);
-
-  void setLong(@NotNull Object host, long value);
-
-  void setDouble(@NotNull Object host, double value);
-
-  void setFloat(@NotNull Object host, float value);
-}
index 3f9aa6c6d18808f38624f153f54e77a35008ddc3..b2d5a1ba72d264a0ad80a876081b827067aaa74d 100644 (file)
@@ -1,20 +1,7 @@
-/*
- * 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.
- */
+// Copyright 2000-2019 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.util.xmlb;
 
+import com.intellij.util.serialization.MutableAccessor;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
index bafc442a3127dd80347e30e37ebd4d0833691801..c9738db67be471192a7bd6e812244d7124dd1814 100644 (file)
@@ -3,6 +3,7 @@ package com.intellij.util.xmlb;
 
 import com.intellij.openapi.util.JDOMUtil;
 import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.serialization.MutableAccessor;
 import com.intellij.util.xmlb.annotations.OptionTag;
 import org.jdom.Attribute;
 import org.jdom.Element;
index 96fdb6c07a2c4c521268b70f8c1db18c5fb246e4..58db333f4c088bc61f767d109ab83ccb02d4de07 100644 (file)
@@ -1,20 +1,7 @@
-/*
- * 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.
- */
+// Copyright 2000-2019 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.util.xmlb;
 
+import com.intellij.util.serialization.MutableAccessor;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
index 0cd3015a10e945a8c37e36ec0c61eb40a1e99f1b..63ebab36767d7285ac41ccd65b308f023682873d 100644 (file)
@@ -1,6 +1,7 @@
 // Copyright 2000-2019 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.util.xmlb;
 
+import com.intellij.util.serialization.MutableAccessor;
 import com.intellij.util.xmlb.annotations.Tag;
 import org.jdom.Element;
 import org.jdom.Text;
index 206ab3a4e3d0007be1f0be71b104629a9a0f8757..9ab6214bffa57cf8abcb4ebb96477714278a6a61 100644 (file)
@@ -1,20 +1,7 @@
-/*
- * 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.
- */
+// Copyright 2000-2019 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.util.xmlb;
 
+import com.intellij.util.serialization.MutableAccessor;
 import org.jdom.Element;
 import org.jdom.Text;
 import org.jetbrains.annotations.NotNull;
index 40b875d40bcce6ea84132bc4c5ce90f85d14cfa6..489042ec2739b72a55a393705adc40be47b56532 100644 (file)
@@ -1,23 +1,9 @@
-/*
- * Copyright 2000-2009 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.
- */
-
+// Copyright 2000-2019 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.util.xmlb;
 
-public class XmlSerializationException extends RuntimeException {
+import com.intellij.util.serialization.SerializationException;
 
+public final class XmlSerializationException extends SerializationException {
   public XmlSerializationException() {
   }
 
index a631cb93fd74dd4b2fc765bffc53c6afc8a9a5d9..5fa7e4e3fd4070dc6b4704468bd6d271917dbaa8 100644 (file)
@@ -1,7 +1,8 @@
-// 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.
+// Copyright 2000-2019 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.util.xmlb;
 
 import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.util.serialization.SerializationException;
 import org.jdom.Document;
 import org.jdom.Element;
 import org.jdom.JDOMException;
@@ -26,12 +27,12 @@ public class XmlSerializer {
   /**
    * Consider to use {@link SkipDefaultValuesSerializationFilters}
    */
-  public static Element serialize(@NotNull Object object) throws XmlSerializationException {
+  public static Element serialize(@NotNull Object object) throws SerializationException {
     return serialize(object, TRUE_FILTER);
   }
 
   @NotNull
-  public static Element serialize(@NotNull Object object, @Nullable SerializationFilter filter) throws XmlSerializationException {
+  public static Element serialize(@NotNull Object object, @Nullable SerializationFilter filter) throws SerializationException {
     return XmlSerializerImpl.serialize(object, filter == null ? TRUE_FILTER : filter);
   }
 
@@ -43,18 +44,18 @@ public class XmlSerializer {
   }
 
   @NotNull
-  public static <T> T deserialize(Document document, Class<T> aClass) throws XmlSerializationException {
+  public static <T> T deserialize(Document document, Class<T> aClass) throws SerializationException {
     return deserialize(document.getRootElement(), aClass);
   }
 
   @NotNull
   @SuppressWarnings({"unchecked"})
-  public static <T> T deserialize(@NotNull Element element, @NotNull Class<T> aClass) throws XmlSerializationException {
+  public static <T> T deserialize(@NotNull Element element, @NotNull Class<T> aClass) throws SerializationException {
     try {
       NotNullDeserializeBinding binding = (NotNullDeserializeBinding)XmlSerializerImpl.serializer.getClassBinding(aClass);
       return (T)binding.deserialize(null, element);
     }
-    catch (XmlSerializationException e) {
+    catch (SerializationException e) {
       throw e;
     }
     catch (Exception e) {
@@ -63,7 +64,7 @@ public class XmlSerializer {
   }
 
   @NotNull
-  public static <T> T deserialize(@NotNull URL url, Class<T> aClass) throws XmlSerializationException {
+  public static <T> T deserialize(@NotNull URL url, Class<T> aClass) throws SerializationException {
     try {
       Document document = JDOMUtil.loadDocument(url);
       document = JDOMXIncluder.resolve(document, url.toExternalForm());
@@ -78,7 +79,7 @@ public class XmlSerializer {
     try {
       getBeanBinding(bean).deserializeInto(bean, element);
     }
-    catch (XmlSerializationException e) {
+    catch (SerializationException e) {
       throw e;
     }
     catch (Exception e) {
@@ -106,7 +107,7 @@ public class XmlSerializer {
     try {
       getBeanBinding(bean).serializeInto(bean, element, filter);
     }
-    catch (XmlSerializationException e) {
+    catch (SerializationException e) {
       throw e;
     }
     catch (Exception e) {
index fecfb1df73e4e6b560a8543602fd50351ba4d286..e57047156995906b380e400b8e6a25e3bc461af6 100644 (file)
@@ -4,6 +4,8 @@ package com.intellij.util.xmlb;
 import com.intellij.openapi.util.JDOMExternalizableStringList;
 import com.intellij.openapi.util.Pair;
 import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.serialization.MutableAccessor;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.xmlb.annotations.CollectionBean;
 import org.jdom.Content;
 import org.jdom.Element;
@@ -130,7 +132,7 @@ public final class XmlSerializerImpl {
   static final XmlSerializer serializer = new XmlSerializer();
 
   @NotNull
-  static Element serialize(@NotNull Object object, @Nullable SerializationFilter filter) throws XmlSerializationException {
+  static Element serialize(@NotNull Object object, @Nullable SerializationFilter filter) throws SerializationException {
     try {
       Class<?> aClass = object.getClass();
       Binding binding = serializer.getClassBinding(aClass);
@@ -143,7 +145,7 @@ public final class XmlSerializerImpl {
         return (Element)binding.serialize(object, null, filter);
       }
     }
-    catch (XmlSerializationException e) {
+    catch (SerializationException e) {
       throw e;
     }
     catch (Exception e) {
index 2e3389c11d144dda292304d016ccddccf2cb4830..5f39ddaf5c628f90cb0ad8cf02e4747b46de8077 100644 (file)
@@ -1,7 +1,8 @@
-// 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.
+// Copyright 2000-2019 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.util.xmlb;
 
 import com.intellij.util.ReflectionUtil;
+import com.intellij.util.serialization.MutableAccessor;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
index 96e0d4b4db237472a8411755a5812667563935a2..c486f6900a9fea5ea29c0072ca54509e54ca2e2d 100644 (file)
@@ -1,4 +1,4 @@
-// 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.
+// Copyright 2000-2019 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 org.jetbrains.idea.devkit.actions
 
 import com.intellij.icons.AllIcons
@@ -27,7 +27,7 @@ import com.intellij.psi.search.*
 import com.intellij.usageView.UsageInfo
 import com.intellij.usages.*
 import com.intellij.util.Processor
-import com.intellij.util.xmlb.XmlSerializationException
+import com.intellij.util.serialization.SerializationException
 import com.intellij.util.xmlb.XmlSerializer
 import org.jetbrains.idea.devkit.util.PsiUtil
 import java.io.File
@@ -62,7 +62,7 @@ class MigrateModuleNamesInSourcesAction : AnAction("Find/Update Module Names in
         XmlSerializer.deserialize(JDOMUtil.load(it.inputStream), ModuleRenamingHistoryState::class.java).oldToNewName
       }
     }
-    catch (e: XmlSerializationException) {
+    catch (e: SerializationException) {
       LOG.error(e)
       return
     }
index 4a6645d9969be357f04a870e43e3075c058d5200..8bee31917c9958c491e7d0f25f99caac06b3db44 100644 (file)
@@ -1,18 +1,4 @@
-/*
- * 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.
- */
+// Copyright 2000-2019 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 org.jetbrains.idea.devkit.actions;
 
 import com.intellij.CommonBundle;
@@ -41,8 +27,8 @@ import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.util.ReflectionUtil;
 import com.intellij.util.containers.FList;
 import com.intellij.util.lang.UrlClassLoader;
-import com.intellij.util.xmlb.MutableAccessor;
-import com.intellij.util.xmlb.XmlSerializationException;
+import com.intellij.util.serialization.MutableAccessor;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.xmlb.XmlSerializer;
 import com.intellij.util.xmlb.XmlSerializerUtil;
 import com.intellij.util.xmlb.annotations.AbstractCollection;
@@ -129,7 +115,7 @@ public class ShowSerializedXmlAction extends DumbAwareAction {
     try {
       element = XmlSerializer.serialize(o);
     }
-    catch (XmlSerializationException e) {
+    catch (SerializationException e) {
       LOG.info(e);
       Throwable cause = e.getCause();
       Messages.showErrorDialog(project, e.getMessage() + (cause != null ? ": " + cause.getMessage() : ""), CommonBundle.getErrorTitle());