0

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?

1 Answer 1

0

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>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.