mirror of
https://github.com/corda/corda.git
synced 2025-05-06 18:48:34 +00:00
universal: prettyPrint
This commit is contained in:
parent
4fdeee5bf8
commit
306a3cdff7
@ -40,6 +40,14 @@ class ActionsBuilder {
|
|||||||
|
|
||||||
infix fun Party.or(party: Party) = setOf(this, party)
|
infix fun Party.or(party: Party) = setOf(this, party)
|
||||||
infix fun Set<Party>.or(party: Party) = this.plus(party)
|
infix fun Set<Party>.or(party: Party) = this.plus(party)
|
||||||
|
|
||||||
|
fun String.givenThat(condition: Perceivable<Boolean>, init: ContractBuilder.() -> Arrangement): Action {
|
||||||
|
val b = ContractBuilder()
|
||||||
|
b.init()
|
||||||
|
val a = Action(this, condition, b.final())
|
||||||
|
actions.add(a)
|
||||||
|
return a
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED")
|
@Suppress("UNUSED")
|
||||||
@ -145,7 +153,7 @@ interface GivenThatResolve {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ActionBuilder(val actors: Set<Party>) {
|
class ActionBuilder(val actors: Set<Party>) {
|
||||||
val actions = mutableListOf<Action>()
|
internal val actions = mutableListOf<Action>()
|
||||||
|
|
||||||
fun String.givenThat(condition: Perceivable<Boolean>, init: ContractBuilder.() -> Arrangement): Action {
|
fun String.givenThat(condition: Perceivable<Boolean>, init: ContractBuilder.() -> Arrangement): Action {
|
||||||
val b = ContractBuilder()
|
val b = ContractBuilder()
|
||||||
|
@ -82,9 +82,6 @@ fun signedByOneOf(actors: Collection<Party>): Perceivable<Boolean> =
|
|||||||
else
|
else
|
||||||
actors.drop(1).fold(signedBy(actors.first())) { total, next -> total or signedBy(next) }
|
actors.drop(1).fold(signedBy(actors.first())) { total, next -> total or signedBy(next) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perceivable based on time
|
* Perceivable based on time
|
||||||
*/
|
*/
|
||||||
|
@ -1,126 +1,187 @@
|
|||||||
package net.corda.contracts.universal
|
package net.corda.contracts.universal
|
||||||
|
|
||||||
|
import net.corda.core.crypto.CompositeKey
|
||||||
|
import net.corda.core.crypto.Party
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
/**
|
private class PrettyPrint(arr : Arrangement) {
|
||||||
* Created by sofusmortensen on 30/12/2016.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
val parties = involvedParties(arr)
|
||||||
|
|
||||||
|
private val sb = StringBuilder()
|
||||||
|
private var indentLevel = 0
|
||||||
|
|
||||||
class PrettyPrint
|
private var atStart = true
|
||||||
{
|
private fun print(msg: String) {
|
||||||
val sb = StringBuilder()
|
if (atStart)
|
||||||
|
repeat(indentLevel, { sb.append(' ') })
|
||||||
|
sb.append(msg)
|
||||||
// fun print
|
atStart = false
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun prettyPrintPerInstant(per: Perceivable<Instant>, indentArg : Int) {
|
|
||||||
|
|
||||||
val sb = StringBuilder()
|
|
||||||
|
|
||||||
var indent = indentArg
|
|
||||||
|
|
||||||
when (per) {
|
|
||||||
is Const -> {
|
|
||||||
print("\"${per.value}\"")
|
|
||||||
}
|
|
||||||
is StartDate -> {
|
|
||||||
print("startDate")
|
|
||||||
}
|
|
||||||
is EndDate -> {
|
|
||||||
print("endDate")
|
|
||||||
}
|
|
||||||
else -> print(per)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun prettyPrintPerBD(per: Perceivable<BigDecimal>, indentArg : Int) {
|
private fun println(message: Any?) {
|
||||||
var indent = indentArg
|
if (atStart)
|
||||||
|
repeat(indentLevel, { sb.append(' ') })
|
||||||
|
sb.appendln(message)
|
||||||
|
atStart = true
|
||||||
|
}
|
||||||
|
|
||||||
fun println(message: Any?)
|
private fun print(msg: Any?) {
|
||||||
|
if (atStart)
|
||||||
|
repeat(indentLevel, { sb.append(' ') })
|
||||||
|
sb.append(msg)
|
||||||
|
atStart = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> indent(body: () -> T): T {
|
||||||
|
indentLevel += 2
|
||||||
|
val rv = body()
|
||||||
|
indentLevel -= 2
|
||||||
|
return rv
|
||||||
|
}
|
||||||
|
|
||||||
|
val partyMap = mutableMapOf<CompositeKey, String>()
|
||||||
|
val usedPartyNames = mutableSetOf<String>()
|
||||||
|
|
||||||
|
fun createPartyName(party : Party) : String
|
||||||
{
|
{
|
||||||
repeat(indent, { print(' ')})
|
val parts = party.name.toLowerCase().split(' ')
|
||||||
System.out.println(message)
|
|
||||||
|
var camelName = parts.drop(1).fold(parts.first()) {
|
||||||
|
s, i -> s + i.first().toUpperCase() + i.drop(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usedPartyNames.contains(camelName)) {
|
||||||
|
camelName += "_" + partyMap.size.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
partyMap.put(party.owningKey, camelName)
|
||||||
|
usedPartyNames.add(camelName)
|
||||||
|
|
||||||
|
return camelName
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
parties.forEach {
|
||||||
|
println( "val ${createPartyName(it)} = Party(\"${it.name}\", \"${it.owningKey}\")" )
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when (per) {
|
fun prettyPrintPerBoolean(per: Perceivable<Boolean>) {
|
||||||
is PerceivableOperation<BigDecimal> -> {
|
when (per) {
|
||||||
prettyPrintPerBD(per.left, indent + 2)
|
is Const -> {
|
||||||
when (per.op)
|
print("\"${per.value}\"")
|
||||||
{
|
|
||||||
Operation.PLUS -> print(" + ")
|
|
||||||
Operation.MINUS -> print(" - ")
|
|
||||||
Operation.DIV -> print(" / ")
|
|
||||||
Operation.TIMES -> print(" * ")
|
|
||||||
else -> print(per.op)
|
|
||||||
}
|
}
|
||||||
prettyPrintPerBD(per.right, indent + 2)
|
is PerceivableOr -> {
|
||||||
|
prettyPrintPerBoolean(per.left)
|
||||||
|
print(" or ")
|
||||||
|
prettyPrintPerBoolean(per.right)
|
||||||
|
}
|
||||||
|
is ActorPerceivable -> {
|
||||||
|
print("signedBy(${partyMap[per.actor.owningKey]})")
|
||||||
|
}
|
||||||
|
else -> print(per)
|
||||||
}
|
}
|
||||||
is Const -> {
|
}
|
||||||
print(per.value)
|
|
||||||
|
fun prettyPrintPerInstant(per: Perceivable<Instant>) {
|
||||||
|
when (per) {
|
||||||
|
is Const -> {
|
||||||
|
print("\"${per.value}\"")
|
||||||
|
}
|
||||||
|
is StartDate -> {
|
||||||
|
print("startDate")
|
||||||
|
}
|
||||||
|
is EndDate -> {
|
||||||
|
print("endDate")
|
||||||
|
}
|
||||||
|
else -> print(per)
|
||||||
}
|
}
|
||||||
is Interest -> {
|
}
|
||||||
println("Interest(")
|
|
||||||
prettyPrintPerBD(per.amount, indent + 2)
|
fun prettyPrintPerBD(per: Perceivable<BigDecimal>) {
|
||||||
print(", \"${per.dayCountConvention}\", ")
|
when (per) {
|
||||||
prettyPrintPerBD(per.amount, indent)
|
is PerceivableOperation<BigDecimal> -> {
|
||||||
print(", ")
|
prettyPrintPerBD(per.left)
|
||||||
prettyPrintPerInstant(per.start, indent)
|
when (per.op) {
|
||||||
print(", ")
|
Operation.PLUS -> print(" + ")
|
||||||
prettyPrintPerInstant(per.end, indent)
|
Operation.MINUS -> print(" - ")
|
||||||
print(")")
|
Operation.DIV -> print(" / ")
|
||||||
|
Operation.TIMES -> print(" * ")
|
||||||
|
else -> print(per.op)
|
||||||
|
}
|
||||||
|
prettyPrintPerBD(per.right)
|
||||||
|
}
|
||||||
|
is Const -> {
|
||||||
|
print(per.value)
|
||||||
|
}
|
||||||
|
is Interest -> {
|
||||||
|
print("Interest(")
|
||||||
|
prettyPrintPerBD(per.amount)
|
||||||
|
print(", \"${per.dayCountConvention}\", ")
|
||||||
|
prettyPrintPerBD(per.amount)
|
||||||
|
print(", ")
|
||||||
|
prettyPrintPerInstant(per.start)
|
||||||
|
print(", ")
|
||||||
|
prettyPrintPerInstant(per.end)
|
||||||
|
print(")")
|
||||||
|
}
|
||||||
|
else -> println(per)
|
||||||
}
|
}
|
||||||
else -> println(per)
|
}
|
||||||
|
|
||||||
|
fun prettyPrint(arr: Arrangement) {
|
||||||
|
|
||||||
|
when (arr) {
|
||||||
|
is Zero -> print("zero")
|
||||||
|
is RollOut -> {
|
||||||
|
println("rollOut(\"${arr.startDate}\".ld, \"${arr.endDate}\".ld, Frequency.${arr.frequency}) { ")
|
||||||
|
indent {
|
||||||
|
prettyPrint(arr.template)
|
||||||
|
}
|
||||||
|
println("}")
|
||||||
|
}
|
||||||
|
is And -> {
|
||||||
|
for (it in arr.arrangements) {
|
||||||
|
prettyPrint(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Continuation -> {
|
||||||
|
println("next()")
|
||||||
|
}
|
||||||
|
is Obligation -> {
|
||||||
|
print("${partyMap[arr.from.owningKey]}.gives( ${partyMap[arr.to.owningKey]}, ")
|
||||||
|
prettyPrintPerBD(arr.amount)
|
||||||
|
println(", ${arr.currency})")
|
||||||
|
}
|
||||||
|
is Actions -> {
|
||||||
|
println("actions {")
|
||||||
|
indent {
|
||||||
|
for ((name, condition, arrangement) in arr.actions) {
|
||||||
|
print("\"$name\".givenThat(")
|
||||||
|
prettyPrintPerBoolean(condition)
|
||||||
|
println(") {")
|
||||||
|
indent {
|
||||||
|
prettyPrint(arrangement)
|
||||||
|
}
|
||||||
|
println("}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println("}")
|
||||||
|
}
|
||||||
|
else -> println(arr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return sb.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun prettyPrint(arr: Arrangement, indentArg: Int = 0) {
|
fun prettyPrint(arr: Arrangement): String {
|
||||||
|
val pb = PrettyPrint(arr)
|
||||||
|
pb.prettyPrint(arr)
|
||||||
|
return pb.toString()
|
||||||
|
}
|
||||||
|
|
||||||
var indent = indentArg
|
|
||||||
|
|
||||||
fun println(message: Any?)
|
|
||||||
{
|
|
||||||
repeat(indent, { print(' ')})
|
|
||||||
System.out.println(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
when (arr) {
|
|
||||||
is Zero -> print("zero")
|
|
||||||
is RollOut -> {
|
|
||||||
println("rollout(\"${arr.startDate}\", \"${arr.endDate}\", Frequency.${arr.frequency}) { ")
|
|
||||||
prettyPrint(arr.template, indent + 2)
|
|
||||||
println("}")
|
|
||||||
}
|
|
||||||
is And -> {
|
|
||||||
for (it in arr.arrangements) {
|
|
||||||
prettyPrint(it, indent + 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is Continuation -> {
|
|
||||||
println("next()")
|
|
||||||
}
|
|
||||||
|
|
||||||
is Obligation -> {
|
|
||||||
println( "\"${arr.from.name}\".gives( \"${arr.to.name}\", ")
|
|
||||||
prettyPrintPerBD(arr.amount, indent)
|
|
||||||
println( ", ${arr.currency})" )
|
|
||||||
}
|
|
||||||
is Actions -> {
|
|
||||||
println("actions {")
|
|
||||||
indent += 2
|
|
||||||
for (it in arr.actions) {
|
|
||||||
println( "\"" + it.name + "\" anytime {")
|
|
||||||
prettyPrint(it.arrangement, indent + 2)
|
|
||||||
println( "}" )
|
|
||||||
}
|
|
||||||
indent -= 2
|
|
||||||
println("}")
|
|
||||||
}
|
|
||||||
else -> println(arr)
|
|
||||||
}
|
|
||||||
}
|
|
@ -12,12 +12,12 @@ fun Instant.toLocalDate(): LocalDate = LocalDate.ofEpochDay(this.epochSecond / 6
|
|||||||
|
|
||||||
fun LocalDate.toInstant(): Instant = Instant.ofEpochSecond(this.toEpochDay() * 60 * 60 * 24)
|
fun LocalDate.toInstant(): Instant = Instant.ofEpochSecond(this.toEpochDay() * 60 * 60 * 24)
|
||||||
|
|
||||||
private fun signingParties(perceivable: Perceivable<Boolean>) : ImmutableSet<CompositeKey> =
|
private fun signingParties(perceivable: Perceivable<Boolean>) : ImmutableSet<Party> =
|
||||||
when (perceivable) {
|
when (perceivable) {
|
||||||
is ActorPerceivable -> ImmutableSet.of( perceivable.actor.owningKey )
|
is ActorPerceivable -> ImmutableSet.of( perceivable.actor )
|
||||||
is PerceivableAnd -> Sets.union( signingParties( perceivable.left ), signingParties(perceivable.right) ).immutableCopy()
|
is PerceivableAnd -> Sets.union( signingParties( perceivable.left ), signingParties(perceivable.right) ).immutableCopy()
|
||||||
is PerceivableOr -> Sets.union( signingParties( perceivable.left ), signingParties(perceivable.right) ).immutableCopy()
|
is PerceivableOr -> Sets.union( signingParties( perceivable.left ), signingParties(perceivable.right) ).immutableCopy()
|
||||||
is TimePerceivable -> ImmutableSet.of<CompositeKey>()
|
is TimePerceivable -> ImmutableSet.of<Party>()
|
||||||
else -> throw IllegalArgumentException("signingParties " + perceivable)
|
else -> throw IllegalArgumentException("signingParties " + perceivable)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,22 +45,24 @@ private fun liablePartiesVisitor(action: Action): ImmutableSet<CompositeKey> {
|
|||||||
/** Returns list of potentially liable parties for a given contract */
|
/** Returns list of potentially liable parties for a given contract */
|
||||||
fun liableParties(contract: Arrangement): Set<CompositeKey> = liablePartiesVisitor(contract)
|
fun liableParties(contract: Arrangement): Set<CompositeKey> = liablePartiesVisitor(contract)
|
||||||
|
|
||||||
private fun involvedPartiesVisitor(action: Action): Set<CompositeKey> =
|
private fun involvedPartiesVisitor(action: Action): Set<Party> =
|
||||||
Sets.union(involvedPartiesVisitor(action.arrangement), signingParties(action.condition)).immutableCopy()
|
Sets.union(involvedPartiesVisitor(action.arrangement), signingParties(action.condition)).immutableCopy()
|
||||||
|
|
||||||
private fun involvedPartiesVisitor(arrangement: Arrangement): ImmutableSet<CompositeKey> =
|
private fun involvedPartiesVisitor(arrangement: Arrangement): ImmutableSet<Party> =
|
||||||
when (arrangement) {
|
when (arrangement) {
|
||||||
is Zero -> ImmutableSet.of<CompositeKey>()
|
is Zero -> ImmutableSet.of<Party>()
|
||||||
is Obligation -> ImmutableSet.of(arrangement.from.owningKey)
|
is Obligation -> ImmutableSet.of(arrangement.from)
|
||||||
|
is RollOut -> involvedPartiesVisitor(arrangement.template)
|
||||||
|
is Continuation -> ImmutableSet.of<Party>()
|
||||||
is And ->
|
is And ->
|
||||||
arrangement.arrangements.fold(ImmutableSet.builder<CompositeKey>(), { builder, k -> builder.addAll(involvedPartiesVisitor(k)) }).build()
|
arrangement.arrangements.fold(ImmutableSet.builder<Party>(), { builder, k -> builder.addAll(involvedPartiesVisitor(k)) }).build()
|
||||||
is Actions ->
|
is Actions ->
|
||||||
arrangement.actions.fold(ImmutableSet.builder<CompositeKey>(), { builder, k -> builder.addAll(involvedPartiesVisitor(k)) }).build()
|
arrangement.actions.fold(ImmutableSet.builder<Party>(), { builder, k -> builder.addAll(involvedPartiesVisitor(k)) }).build()
|
||||||
else -> throw IllegalArgumentException()
|
else -> throw IllegalArgumentException(arrangement.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** returns list of involved parties for a given contract */
|
/** returns list of involved parties for a given contract */
|
||||||
fun involvedParties(arrangement: Arrangement): Set<CompositeKey> = involvedPartiesVisitor(arrangement)
|
fun involvedParties(arrangement: Arrangement): Set<Party> = involvedPartiesVisitor(arrangement)
|
||||||
|
|
||||||
fun replaceParty(perceivable: Perceivable<Boolean>, from: Party, to: Party): Perceivable<Boolean> =
|
fun replaceParty(perceivable: Perceivable<Boolean>, from: Party, to: Party): Perceivable<Boolean> =
|
||||||
when (perceivable) {
|
when (perceivable) {
|
||||||
|
@ -6,6 +6,7 @@ import net.corda.core.contracts.Frequency
|
|||||||
import net.corda.core.contracts.Tenor
|
import net.corda.core.contracts.Tenor
|
||||||
import net.corda.core.utilities.DUMMY_NOTARY
|
import net.corda.core.utilities.DUMMY_NOTARY
|
||||||
import net.corda.testing.transaction
|
import net.corda.testing.transaction
|
||||||
|
import org.junit.Ignore
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
@ -164,8 +165,6 @@ class Cap {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun issue() {
|
fun issue() {
|
||||||
prettyPrint(contractInitial)
|
|
||||||
|
|
||||||
transaction {
|
transaction {
|
||||||
output { stateInitial }
|
output { stateInitial }
|
||||||
timestamp(TEST_TX_TIME_1)
|
timestamp(TEST_TX_TIME_1)
|
||||||
@ -311,4 +310,9 @@ class Cap {
|
|||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test @Ignore
|
||||||
|
fun `pretty print`() {
|
||||||
|
println ( prettyPrint(contractInitial) )
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user