This is how my custom PersistentStateComponent
subclass looks like:
@State(name = "Configurations", storages = [Storage("conf.xml")])
@Service(Service.Level.PROJECT)
class CustomConfigurationService : PersistentStateComponent<CustomConfigurationService> {
var configurations = Configurations()
override fun getState() = this
override fun loadState(service: CustomConfigurationService) {
XmlSerializerUtil.copyBean(service, this)
}
// ...
}
data class Configurations(
val aBoolean: Boolean = false,
val aString: String? = null,
val anotherString: String? = null
)
This is how the configurations are stored (after being changed via the UI):
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Configurations">
<option name="configurations">
<Configurations />
</option>
</component>
</project>
If I change the super type to PersistentStateComponent<Configurations>
, the file is not created at all.
Why doesn't IntelliJ serialize the Configurations
object's properties as well? What can I do, other than placing Configurations
's properties directly inside CustomConfigurationService
?
It turns out that I was terribly misguided. Here's how the final code looks like:
import com.intellij.openapi.components.BaseState
class Configurations : BaseState() {
// property() and string() are BaseState methods
var aBoolean by property(false)
var aString by string(null)
var anotherString by string(null)
}
import com.intellij.openapi.components.SimplePersistentStateComponent
import com.intellij.util.xmlb.XmlSerializerUtil
@State(name = "Configurations", storages = [Storage("conf.xml")])
@Service(Service.Level.PROJECT)
class CustomConfigurationService :
// This takes care of everything else and gives us a .state property
SimplePersistentStateComponent<Configurations>(Configurations()) {
// ...which I shadow using this other property.
override var configurations: Configurations
get() = state
set(value) = XmlSerializerUtil.copyBean(value, state)
companion object {
fun getInstance() = service<ConfigurationService>()
}
}
conf.xml
's contents eventually looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Configurations">
<option name="aBoolean" value="true" />
<option name="aString" value="Foobar">
</component>
</project>