State Model¶
Sample State¶
Let’s start with a simple state model:
/** Our contract class */
class NewsPaperContract: Contract {
/** State definition */
@LeanStateModel
interface NewsPaper {
val publisher: Party?
val author: Party
//...
}
}
Targeting a Contract¶
In the above example the NewsPaper
type is contained in a Corda Contract
so there is no need
to specify the contract type target for the generated ContractState
. If NewsPaper
was in a standalone
file, we would specify the contract using LeanStateModel.contractClass
:
/** Standalone state definition */
@LeanStateModel(contractClass = NewsPaperContract::class)
interface NewsPaper {
val publisher: Party?
val author: Party
//...
}
or using a classname string with LeanStateModel.contractClassName
:
/** Standalone state definition */
@LeanStateModel(contractClassName = "my.package.NewsPaperContract")
interface NewsPaper {
val publisher: Party?
val author: Party
//...
}
Property Initializers¶
To add default value initializers to your contract state, use @LeanStateProperty.initializer
like
shown bellow:
@LeanStateModel
interface NewsPaper {
//...
@get:LeanStateProperty(initializer = "NewsPaperStatus.FOOBAR")
val status: NewsPaperStatus
}
Default Participants¶
The default strategy used by the annotation processor scans your interface and uses members of the following types
to create the default participants
implementation:
net.corda.core.identity.Party
net.corda.core.identity.AbstractParty
net.corda.core.identity.AnonymousParty
java.security.PublicKey
- Types with a proper
party
member, e.g.com.github.manosbatsis.vaultaire.dto.AccountParty
- Any collection parameterised with one of the above
Overriding LinearState¶
If besides all other options available you still want to directly customise the overrides
for LinearState
you can so it in your interface. The annotation processor will honor them by not generating its own.
/** State definition */
@LeanStateModel
interface NewsPaper: LinearState {
val publisher: Party?
val author: Party
//...
// Optional, no need to add or override explicitly
override val linearId: UniqueIdentifier
// Optionally override LinearState.participants
// if you don't want the implementation generated by default
override val participants get() = listOfNotNull(publisher?.party, author.party)
}
Custom Table Name¶
To customise the generated @Table
annotation use @LeanStateModel.tableName
like
shown bellow:
@LeanStateModel(tableName = "custom_table_name")
interface NewsPaper {
//...
}
Custom Migration Resource¶
To customise the generated MappedSchema
implementation for using a custom Liquibase migrationResource
,
use @LeanStateModel.migrationResource
like shown bellow:
@LeanStateModel(migrationResource = "custom-newspaper-schema-v1.changelog-master.xml")
interface NewsPaper {
//...
}
this will generate
Overriding QueryableState¶
If besides all other options available you still want to directly customise overrides for QueryableState
you can do so in your interface. The annotation processor will honor them by not generating its own.
@LeanStateModel
interface NewsPaper: QueryableState {
val publisher: Party?
val author: Party
//...
// Optional, only override to use a custom implementation
// VS the default strategy.
override fun generateMappedObject(schema: MappedSchema) = NewsPaperPersistentState(
// ...
)
// Only extend QueryableState and override if you don't want the implementation generated by default
override fun supportedSchemas() = listOf(SchemaV1)
// Only add if you explicitly implement supportedSchemas()
object Schema
object NSchemaV1 : MappedSchema(NewsPaperSchema::class.java, 1, listOf(NewsPaperPersistentState::class.java))
}
Property Mapping Modes¶
[LeanStateModel] and [LeanStateProperty] annotations allow configuration of Contract to Persistent State property mappings using one or more of the following:
NATIVE
: Will generate PersistentState fields using the original ContractState field if possible.STRINGIFY
: Will generate string-based PersistentState field variants where applicable, suffixing their names with “String”.EXPANDED
: Will generate PersistentState fields by expanding applicable types to properties corresponding to their individual members.
// Tweak mapping modes at type level,
// default is [PropertyMappingMode.EXPANDED],
@LeanStateModel(mappingModes = [
PropertyMappingMode.NATIVE,
PropertyMappingMode.STRINGIFY,
PropertyMappingMode.EXPANDED]
)
interface NewsPaper {
val publisher: Party?
// Tweak modes at property level
@LeanStateProperty(mappingModes = [
PropertyMappingMode.STRINGIFY])
val author: Party
//...
}
JPA Overrides¶
JPA @Column
annotations found in your model interface will be copied as-is,
overriding the annotation processor defaults.
@LeanStateModel
interface NewsPaper {
// Override JPA Column generation
@get:Column(name = "alt_title", length = 500)
val alternativeTitle: String?
//...
}