extract object serializer annotations to external module for runtime gradle needs, extract JdomSerializer to reduce dependency on object serializer (projectModel impl doesn't depend on it anymore and do not export it)

GitOrigin-RevId: 4079c283416c767b2c0a4330d6fa4e9a471c7ec8
This commit is contained in:
Vladimir Krivosheev
2019-05-15 14:07:15 +03:00
committed by intellij-monorepo-bot
parent b0aafa9204
commit daeb83f9ef
24 changed files with 191 additions and 118 deletions
+1
View File
@@ -596,6 +596,7 @@
<module fileurl="file://$PROJECT_DIR$/platform/platform-main/intellij.platform.main.iml" filepath="$PROJECT_DIR$/platform/platform-main/intellij.platform.main.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/object-serializer/intellij.platform.objectSerializer.iml" filepath="$PROJECT_DIR$/platform/object-serializer/intellij.platform.objectSerializer.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/object-serializer/intellij.platform.objectSerializer.tests.iml" filepath="$PROJECT_DIR$/platform/object-serializer/intellij.platform.objectSerializer.tests.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/object-serializer/intellij.platform.objectSerializer.annotations.iml" filepath="$PROJECT_DIR$/platform/object-serializer/intellij.platform.objectSerializer.annotations.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/projectModel-api/intellij.platform.projectModel.iml" filepath="$PROJECT_DIR$/platform/projectModel-api/intellij.platform.projectModel.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/projectModel-impl/intellij.platform.projectModel.impl.iml" filepath="$PROJECT_DIR$/platform/projectModel-impl/intellij.platform.projectModel.impl.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/remote-servers/api/intellij.platform.remoteServers.iml" filepath="$PROJECT_DIR$/platform/remote-servers/api/intellij.platform.remoteServers.iml" />
@@ -12,6 +12,5 @@
<orderEntry type="module" module-name="intellij.platform.projectModel" />
<orderEntry type="library" name="kotlin-stdlib-jdk8" level="project" />
<orderEntry type="module" module-name="intellij.platform.uast" exported="" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer" />
</component>
</module>
+1
View File
@@ -61,6 +61,7 @@
<orderEntry type="library" name="jaxb-api" level="project" />
<orderEntry type="library" name="javax.activation" level="project" />
<orderEntry type="library" scope="RUNTIME" name="jaxb-runtime" level="project" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer.annotations" />
</component>
<component name="copyright">
<Base>
@@ -13,6 +13,5 @@
<orderEntry type="module" module-name="intellij.platform.core" />
<orderEntry type="module" module-name="intellij.platform.projectModel" />
<orderEntry type="module" module-name="intellij.platform.editor" exported="" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer" />
</component>
</module>
@@ -65,6 +65,7 @@ class CommunityRepositoryModules {
"intellij.platform.lvcs.impl",
"intellij.platform.ide.impl",
"intellij.platform.objectSerializer",
"intellij.platform.objectSerializer.annotations",
"intellij.platform.projectModel.impl",
"intellij.platform.scriptDebugger.protocolReaderRuntime",
"intellij.regexp",
@@ -15,7 +15,6 @@
<orderEntry type="library" name="kotlin-stdlib-jdk8" level="project" />
<orderEntry type="library" name="JDOM" level="project" />
<orderEntry type="library" name="jetbrains-annotations" level="project" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer" />
<orderEntry type="module" module-name="intellij.platform.util.ex" />
</component>
</module>
@@ -19,5 +19,6 @@
<orderEntry type="library" name="JDOM" level="project" />
<orderEntry type="library" scope="RUNTIME" name="javassist" level="project" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer.annotations" />
</component>
</module>
@@ -34,5 +34,7 @@
<orderEntry type="module" module-name="intellij.java.execution.impl" />
<orderEntry type="module" module-name="intellij.java.compiler.tests" scope="TEST" />
<orderEntry type="library" name="kotlin-reflect" level="project" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer.annotations" />
</component>
</module>
@@ -19,6 +19,5 @@
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
<orderEntry type="library" scope="TEST" name="hamcrest" level="project" />
<orderEntry type="module" module-name="intellij.platform.util.ex" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer" />
</component>
</module>
@@ -0,0 +1,17 @@
// 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.serialization;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Kotlin: `@PropertyMapping("name", "name2")`
* Java: `@PropertyMapping({"name", "name2"})`
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.CONSTRUCTOR)
public @interface PropertyMapping {
String[] value();
}
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/annotations">
<sourceFolder url="file://$MODULE_DIR$/annotations" isTestSource="false" packagePrefix="com.intellij.serialization" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
@@ -18,5 +18,6 @@
<orderEntry type="module" module-name="intellij.platform.util.ex" />
<orderEntry type="module" module-name="intellij.platform.core" />
<orderEntry type="module" module-name="intellij.platform.projectModel" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer.annotations" />
</component>
</module>
@@ -13,5 +13,6 @@
<orderEntry type="module" module-name="intellij.platform.testExtensions" scope="TEST" />
<orderEntry type="library" scope="TEST" name="assertJ" level="project" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer.annotations" scope="TEST" />
</component>
</module>
@@ -0,0 +1,2 @@
# 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.
com.intellij.configurationStore.JdomSerializerImpl
@@ -17,13 +17,6 @@ internal typealias ValueReader = IonReader
internal typealias ValueWriter = IonWriter
typealias BeanConstructed = (instance: Any) -> Any
/**
* Kotlin: `@PropertyMapping(["name", "name2"])`
* Java: `@PropertyMapping({"name", "name2"})`
*/
@Target(AnnotationTarget.CONSTRUCTOR)
annotation class PropertyMapping(val value: Array<String>)
internal val defaultWriteConfiguration = WriteConfiguration()
internal val LOG = logger<ObjectSerializer>()
@@ -1,9 +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.
@file:JvmName("XmlSerializer")
package com.intellij.configurationStore
import com.intellij.openapi.components.BaseState
import com.intellij.openapi.components.PersistentStateComponent
import com.intellij.openapi.util.JDOMUtil
import com.intellij.reference.SoftReference
import com.intellij.serialization.BindingProducer
@@ -14,15 +12,13 @@ import com.intellij.util.io.URLUtil
import com.intellij.util.xmlb.*
import org.jdom.Element
import org.jdom.JDOMException
import org.jetbrains.annotations.ApiStatus
import java.io.IOException
import java.lang.reflect.Type
import java.net.URL
private val skipDefaultsSerializationFilter = ThreadLocal<SoftReference<SkipDefaultsSerializationFilter>>()
@ApiStatus.Internal
fun getDefaultSerializationFilter(): SkipDefaultsSerializationFilter {
private fun doGetDefaultSerializationFilter(): SkipDefaultsSerializationFilter {
var result = SoftReference.dereference(skipDefaultsSerializationFilter.get())
if (result == null) {
result = object : SkipDefaultsSerializationFilter() {
@@ -40,111 +36,98 @@ fun getDefaultSerializationFilter(): SkipDefaultsSerializationFilter {
return result
}
@JvmOverloads
fun <T : Any> T.serialize(filter: SerializationFilter? = getDefaultSerializationFilter(), createElementIfEmpty: Boolean = false): Element? {
try {
val clazz = javaClass
val binding = serializer.getRootBinding(clazz)
return if (binding is BeanBinding) {
// top level expects not null (null indicates error, empty element will be omitted)
binding.serialize(this, createElementIfEmpty, filter)
internal class JdomSerializerImpl : JdomSerializer {
override fun getDefaultSerializationFilter() = doGetDefaultSerializationFilter()
override fun <T : Any> serialize(obj: T, filter: SerializationFilter?, createElementIfEmpty: Boolean): Element? {
try {
val clazz = javaClass
val binding = serializer.getRootBinding(clazz)
return if (binding is BeanBinding) {
// top level expects not null (null indicates error, empty element will be omitted)
binding.serialize(this, createElementIfEmpty, filter)
}
else {
binding.serialize(this, null, filter) as Element
}
}
else {
binding.serialize(this, null, filter) as Element
catch (e: SerializationException) {
throw e
}
catch (e: Exception) {
throw XmlSerializationException("Can't serialize instance of ${this.javaClass}", e)
}
}
catch (e: SerializationException) {
throw e
override fun serializeObjectInto(o: Any, target: Element, filter: SerializationFilter?) {
if (o is Element) {
val iterator = o.children.iterator()
for (child in iterator) {
iterator.remove()
target.addContent(child)
}
val attributeIterator = o.attributes.iterator()
for (attribute in attributeIterator) {
attributeIterator.remove()
target.setAttribute(attribute)
}
return
}
val beanBinding = serializer.getRootBinding(o.javaClass) as KotlinAwareBeanBinding
beanBinding.serializeInto(o, target, filter ?: doGetDefaultSerializationFilter())
}
catch (e: Exception) {
throw XmlSerializationException("Can't serialize instance of ${this.javaClass}", e)
override fun <T> deserialize(element: Element, clazz: Class<T>): T {
if (clazz == Element::class.java) {
@Suppress("UNCHECKED_CAST")
return this as T
}
@Suppress("UNCHECKED_CAST")
try {
return (serializer.getRootBinding(clazz) as NotNullDeserializeBinding).deserialize(null, element) as T
}
catch (e: SerializationException) {
throw e
}
catch (e: Exception) {
throw XmlSerializationException("Cannot deserialize class ${clazz.name}", e)
}
}
override fun deserializeInto(element: Element, bean: Any) {
try {
(serializer.getRootBinding(bean.javaClass) as BeanBinding).deserializeInto(bean, element)
}
catch (e: SerializationException) {
throw e
}
catch (e: Exception) {
throw XmlSerializationException(e)
}
}
override fun <T> deserialize(url: URL, aClass: Class<T>): T {
try {
@Suppress("DEPRECATION")
var document = JDOMUtil.loadDocument(URLUtil.openStream(url))
document = JDOMXIncluder.resolve(document, url.toExternalForm())
return deserialize(document.rootElement, aClass)
}
catch (e: IOException) {
throw XmlSerializationException(e)
}
catch (e: JDOMException) {
throw XmlSerializationException(e)
}
}
}
fun deserializeBaseStateWithCustomNameFilter(state: BaseState, excludedPropertyNames: Collection<String>): Element? {
val binding = serializer.getRootBinding(state.javaClass) as KotlinAwareBeanBinding
return binding.serializeBaseStateInto(state, null, getDefaultSerializationFilter(), excludedPropertyNames)
}
inline fun <reified T: Any> Element.deserialize(): T = deserialize(T::class.java)
fun <T> Element.deserialize(clazz: Class<T>): T {
if (clazz == Element::class.java) {
@Suppress("UNCHECKED_CAST")
return this as T
}
@Suppress("UNCHECKED_CAST")
try {
return (serializer.getRootBinding(clazz) as NotNullDeserializeBinding).deserialize(null, this) as T
}
catch (e: SerializationException) {
throw e
}
catch (e: Exception) {
throw XmlSerializationException("Cannot deserialize class ${clazz.name}", e)
}
}
fun <T> deserialize(url: URL, aClass: Class<T>): T {
try {
@Suppress("DEPRECATION")
var document = JDOMUtil.loadDocument(URLUtil.openStream(url))
document = JDOMXIncluder.resolve(document, url.toExternalForm())
return document.rootElement.deserialize(aClass)
}
catch (e: IOException) {
throw XmlSerializationException(e)
}
catch (e: JDOMException) {
throw XmlSerializationException(e)
}
}
fun Element.deserializeInto(bean: Any) {
try {
(serializer.getRootBinding(bean.javaClass) as BeanBinding).deserializeInto(bean, this)
}
catch (e: SerializationException) {
throw e
}
catch (e: Exception) {
throw XmlSerializationException(e)
}
}
@JvmOverloads
fun <T> deserializeAndLoadState(component: PersistentStateComponent<T>, element: Element, clazz: Class<T> = ComponentSerializationUtil.getStateClass<T>(component::class.java)) {
val state = element.deserialize(clazz)
(state as? BaseState)?.resetModificationCount()
component.loadState(state)
}
fun serializeStateInto(component: PersistentStateComponent<*>, element: Element) {
component.state?.let {
serializeObjectInto(it, element)
}
}
@JvmOverloads
fun serializeObjectInto(o: Any, target: Element, filter: SerializationFilter? = null) {
if (o is Element) {
val iterator = o.children.iterator()
for (child in iterator) {
iterator.remove()
target.addContent(child)
}
val attributeIterator = o.attributes.iterator()
for (attribute in attributeIterator) {
attributeIterator.remove()
target.setAttribute(attribute)
}
return
}
val beanBinding = serializer.getRootBinding(o.javaClass) as KotlinAwareBeanBinding
beanBinding.serializeInto(o, target, filter ?: getDefaultSerializationFilter())
return binding.serializeBaseStateInto(state, null, doGetDefaultSerializationFilter(), excludedPropertyNames)
}
private val serializer = MyXmlSerializer()
@@ -67,7 +67,7 @@ private class ContainingBean {
var b2: Bean3? = null
}
private class Bean2 @PropertyMapping(["name"]) constructor(@JvmField val name: String)
private class Bean2 @PropertyMapping("name") constructor(@JvmField val name: String)
private class Bean3 {
@JvmField
@@ -75,8 +75,8 @@ private class Bean3 {
}
@Suppress("UNUSED_PARAMETER", "unused")
private class NoDefaultConstructorBean @PropertyMapping(["someParameter", "intList"]) constructor(@JvmField val someParameter: String,
private class NoDefaultConstructorBean @PropertyMapping("someParameter", "intList") constructor(@JvmField val someParameter: String,
@JvmField val intList: List<Int>)
@Suppress("UNUSED_PARAMETER", "unused")
private class NullableArgBean @PropertyMapping(["p", "p2", "p3"]) constructor(@JvmField val p: String?, @JvmField val p2: String?, @JvmField val p3: String?)
private class NullableArgBean @PropertyMapping("p", "p2", "p3") constructor(@JvmField val p: String?, @JvmField val p2: String?, @JvmField val p3: String?)
@@ -39,6 +39,5 @@
<orderEntry type="library" exported="" name="rd-core" level="project" />
<orderEntry type="library" scope="RUNTIME" name="netty-handler-proxy" level="project" />
<orderEntry type="module" module-name="intellij.platform.util.ex" exported="" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer" />
</component>
</module>
@@ -59,5 +59,6 @@
<orderEntry type="library" scope="RUNTIME" name="jaxb-runtime" level="project" />
<orderEntry type="library" scope="RUNTIME" name="javax.annotation-api" level="project" />
<orderEntry type="library" name="kotlin-reflect" level="project" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer" scope="RUNTIME" />
</component>
</module>
@@ -0,0 +1,62 @@
// 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:JvmName("XmlSerializer")
package com.intellij.configurationStore
import com.intellij.openapi.components.BaseState
import com.intellij.openapi.components.PersistentStateComponent
import com.intellij.util.xmlb.SerializationFilter
import com.intellij.util.xmlb.SkipDefaultsSerializationFilter
import org.jdom.Element
import org.jetbrains.annotations.ApiStatus
import java.net.URL
import java.util.*
private val serializer: JdomSerializer = ServiceLoader.load<JdomSerializer>(JdomSerializer::class.java).first()
@ApiStatus.Internal
fun getDefaultSerializationFilter() = serializer.getDefaultSerializationFilter()
@JvmOverloads
fun <T : Any> T.serialize(filter: SerializationFilter? = serializer.getDefaultSerializationFilter(), createElementIfEmpty: Boolean = false): Element? {
return serializer.serialize(this, filter, createElementIfEmpty)
}
inline fun <reified T: Any> Element.deserialize(): T = deserialize(T::class.java)
fun <T> Element.deserialize(clazz: Class<T>): T = serializer.deserialize(this, clazz)
fun Element.deserializeInto(bean: Any) = serializer.deserializeInto(this, bean)
fun <T> deserialize(url: URL, aClass: Class<T>): T = serializer.deserialize(url, aClass)
@JvmOverloads
fun <T> deserializeAndLoadState(component: PersistentStateComponent<T>, element: Element, clazz: Class<T> = ComponentSerializationUtil.getStateClass<T>(component::class.java)) {
val state = serializer.deserialize(element, clazz)
(state as? BaseState)?.resetModificationCount()
component.loadState(state)
}
@JvmOverloads
fun serializeObjectInto(o: Any, target: Element, filter: SerializationFilter? = null) {
serializer.serializeObjectInto(o, target, filter)
}
fun serializeStateInto(component: PersistentStateComponent<*>, element: Element) {
component.state?.let {
serializer.serializeObjectInto(it, element)
}
}
interface JdomSerializer {
fun getDefaultSerializationFilter(): SkipDefaultsSerializationFilter
fun <T : Any> serialize(obj: T, filter: SerializationFilter?, createElementIfEmpty: Boolean = false): Element?
fun serializeObjectInto(o: Any, target: Element, filter: SerializationFilter? = null)
fun <T> deserialize(element: Element, clazz: Class<T>): T
fun deserializeInto(element: Element, bean: Any)
fun <T> deserialize(url: URL, aClass: Class<T>): T
}
@@ -14,7 +14,6 @@
<orderEntry type="module" module-name="intellij.platform.jps.model.serialization" exported="" />
<orderEntry type="library" name="kotlin-stdlib-jdk8" level="project" />
<orderEntry type="library" name="kotlinx-coroutines-jdk8" level="project" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer" exported="" />
<orderEntry type="module" module-name="intellij.platform.util.ex" exported="" />
</component>
</module>
@@ -25,5 +25,6 @@
<orderEntry type="library" scope="TEST" name="gson" level="project" />
<orderEntry type="module" module-name="intellij.yaml" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.configurationStore.impl" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer" />
</component>
</module>
+2 -1
View File
@@ -9,7 +9,7 @@
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
</content>
<content url="file://$MODULE_DIR$/src">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
@@ -25,5 +25,6 @@
<orderEntry type="library" name="Objenesis" level="project" />
<orderEntry type="library" name="Groovy" level="project" />
<orderEntry type="library" name="gson" level="project" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer.annotations" />
</component>
</module>