mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
CORDA-1497 replace missing validation (#4349)
This commit is contained in:
parent
9232b3637b
commit
c2986ca31d
@ -53,7 +53,7 @@ data class EnumTransforms(
|
||||
}
|
||||
|
||||
private fun validate(constants: Map<String, Int>): EnumTransforms {
|
||||
validateNoCycles()
|
||||
validateNoCycles(constants)
|
||||
|
||||
// For any name in the enum's constants, get all its previous names
|
||||
fun renameChain(newName: String): Sequence<String> = generateSequence(newName) { renames[it] }
|
||||
@ -85,12 +85,16 @@ data class EnumTransforms(
|
||||
*
|
||||
* By detecting each condition, and updating the chains accordingly, we can perform cycle-detection in O(n) time.
|
||||
*/
|
||||
private fun validateNoCycles() {
|
||||
private fun validateNoCycles(constants: Map<String, Int>) {
|
||||
// We keep track of chains in both directions
|
||||
val chainStartsToEnds = mutableMapOf<String, String>()
|
||||
val chainEndsToStarts = mutableMapOf<String, String>()
|
||||
|
||||
for ((from, to) in renames) {
|
||||
for ((to, from) in renames) {
|
||||
if (from in constants) {
|
||||
throw InvalidEnumTransformsException("Rename from $from to $to would rename existing constant in $constants.keys")
|
||||
}
|
||||
|
||||
// If there is an existing chain, starting at the "to" node of this edge, then there is a chain from this edge's
|
||||
// "from" to that chain's end.
|
||||
val newEnd = chainStartsToEnds[to] ?: to
|
||||
@ -105,13 +109,17 @@ data class EnumTransforms(
|
||||
}
|
||||
|
||||
// Either update, or create, the chains in both directions.
|
||||
chainStartsToEnds[from] = newEnd
|
||||
chainEndsToStarts[to] = newStart
|
||||
|
||||
// If we have joined two previously unconnected chains, update their starts and ends accordingly.
|
||||
chainStartsToEnds[newStart] = newEnd
|
||||
chainEndsToStarts[newEnd] = newStart
|
||||
}
|
||||
|
||||
// Make sure that every rename chain ends with a known constant.
|
||||
for ((chainStart, chainEnd) in chainStartsToEnds) {
|
||||
if (chainEnd !in constants) {
|
||||
throw InvalidEnumTransformsException(
|
||||
"Rename chain from $chainStart to $chainEnd does not end with a known constant in ${constants.keys}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,6 +51,36 @@ class EnumTransformationTests {
|
||||
}
|
||||
}
|
||||
|
||||
@CordaSerializationTransformRenames(
|
||||
CordaSerializationTransformRename(from = "P", to = "Q"),
|
||||
CordaSerializationTransformRename(from = "Q", to = "R")
|
||||
)
|
||||
enum class DanglingRenames { A, B, C }
|
||||
|
||||
@Test
|
||||
fun renameCycleDoesNotTerminateInConstant() {
|
||||
assertFailsWith<InvalidEnumTransformsException> {
|
||||
EnumTransforms.build(
|
||||
TransformsAnnotationProcessor.getTransformsSchema(DanglingRenames::class.java),
|
||||
DanglingRenames::class.java.constants)
|
||||
}
|
||||
}
|
||||
|
||||
@CordaSerializationTransformRenames(
|
||||
CordaSerializationTransformRename(from = "P", to = "Q"),
|
||||
CordaSerializationTransformRename(from = "Q", to = "R")
|
||||
)
|
||||
enum class RenamesExisting { Q, R, S }
|
||||
|
||||
@Test
|
||||
fun renamesRenameExistingConstant() {
|
||||
assertFailsWith<InvalidEnumTransformsException> {
|
||||
EnumTransforms.build(
|
||||
TransformsAnnotationProcessor.getTransformsSchema(RenamesExisting::class.java),
|
||||
RenamesExisting::class.java.constants)
|
||||
}
|
||||
}
|
||||
|
||||
private val Class<*>.constants: Map<String, Int> get() =
|
||||
enumConstants.asSequence().mapIndexed { index, constant -> constant.toString() to index }.toMap()
|
||||
}
|
Loading…
Reference in New Issue
Block a user