From c062d48e6e3f70fe25665973bfdfd2eaeee345a7 Mon Sep 17 00:00:00 2001 From: Katarzyna Streich Date: Fri, 5 May 2017 14:00:55 +0100 Subject: [PATCH] Explorer x500names (#631) Format party names in explorer, so they look nice after X500 name changes. --- .../explorer/formatters/PartyNameFormatter.kt | 15 +++++++++ .../net/corda/explorer/views/MainView.kt | 3 +- .../net/corda/explorer/views/Network.kt | 6 ++-- .../corda/explorer/views/TransactionViewer.kt | 32 ++++++++++++++++--- .../views/cordapps/cash/CashViewer.kt | 8 +++-- .../views/cordapps/cash/NewTransaction.kt | 9 +++--- .../net/corda/explorer/views/Network.fxml | 6 ++-- 7 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 tools/explorer/src/main/kotlin/net/corda/explorer/formatters/PartyNameFormatter.kt diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/formatters/PartyNameFormatter.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/formatters/PartyNameFormatter.kt new file mode 100644 index 0000000000..8f011a12c7 --- /dev/null +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/formatters/PartyNameFormatter.kt @@ -0,0 +1,15 @@ +package net.corda.explorer.formatters + +import net.corda.core.crypto.Party +import net.corda.core.crypto.commonName +import org.bouncycastle.asn1.x500.X500Name + +object PartyNameFormatter { + val short = object : Formatter { + override fun format(value: String) = X500Name(value).commonName + } + + val full = object : Formatter { + override fun format(value: String): String = value + } +} diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/MainView.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/MainView.kt index cd75cb262f..c375122b04 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/MainView.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/MainView.kt @@ -23,6 +23,7 @@ import net.corda.client.jfx.model.observableList import net.corda.client.jfx.model.observableValue import net.corda.client.jfx.utils.ChosenList import net.corda.client.jfx.utils.map +import net.corda.explorer.formatters.PartyNameFormatter import net.corda.explorer.model.CordaViewModel import tornadofx.* @@ -49,7 +50,7 @@ class MainView : View() { init { // Header - userButton.textProperty().bind(myIdentity.map { it?.legalIdentity?.name }) + userButton.textProperty().bind(myIdentity.map { it?.legalIdentity?.let { PartyNameFormatter.short.format(it.name) } }) exit.setOnAction { (root.scene.window as Stage).fireEvent(WindowEvent(root.scene.window, WindowEvent.WINDOW_CLOSE_REQUEST)) } diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt index 1e1c1f5144..72dcb0dae8 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt @@ -29,6 +29,7 @@ import net.corda.core.contracts.ContractState import net.corda.core.crypto.Party import net.corda.core.crypto.toBase58String import net.corda.core.node.NodeInfo +import net.corda.explorer.formatters.PartyNameFormatter import net.corda.explorer.model.CordaView import tornadofx.* @@ -84,7 +85,7 @@ class Network : CordaView() { private fun NodeInfo.render(): MapViewComponents { val node = this - val mapLabel = label(node.legalIdentity.name) { + val mapLabel = label(PartyNameFormatter.short.format(node.legalIdentity.name)) { graphic = FontAwesomeIconView(FontAwesomeIcon.DOT_CIRCLE_ALT) contentDisplay = ContentDisplay.TOP val coordinate = Bindings.createObjectBinding({ @@ -98,10 +99,11 @@ class Network : CordaView() { val button = button { graphic = vbox { - label(node.legalIdentity.name) { font = Font.font(font.family, FontWeight.BOLD, 15.0) } + label(PartyNameFormatter.short.format(node.legalIdentity.name)) { font = Font.font(font.family, FontWeight.BOLD, 15.0) } gridpane { hgap = 5.0 vgap = 5.0 + row("Full name :") { label(PartyNameFormatter.full.format(node.legalIdentity.name)) } row("Pub Key :") { copyableLabel(SimpleObjectProperty(node.legalIdentity.owningKey.toBase58String())) } row("Services :") { label(node.advertisedServices.map { it.info }.joinToString(", ")) } node.physicalLocation?.apply { row("Location :") { label(this@apply.description) } } diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt index 07bb3fb55a..b4f2a1bcc9 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt @@ -30,6 +30,8 @@ import net.corda.core.crypto.toStringShort import net.corda.core.node.NodeInfo import net.corda.explorer.AmountDiff import net.corda.explorer.formatters.AmountFormatter +import net.corda.explorer.formatters.Formatter +import net.corda.explorer.formatters.PartyNameFormatter import net.corda.explorer.identicon.identicon import net.corda.explorer.identicon.identiconToolTip import net.corda.explorer.model.CordaView @@ -132,8 +134,22 @@ class TransactionViewer : CordaView("Transactions") { } } column("Output", Transaction::outputs).cellFormat { text = it.toText() } - column("Input Party", Transaction::inputParties).cellFormat { text = it.flatten().map { it.value?.legalIdentity?.name }.filterNotNull().toSet().joinToString() } - column("Output Party", Transaction::outputParties).cellFormat { text = it.flatten().map { it.value?.legalIdentity?.name }.filterNotNull().toSet().joinToString() } + column("Input Party", Transaction::inputParties).setCustomCellFactory { + label { + text = it.formatJoinPartyNames(formatter = PartyNameFormatter.short) + tooltip { + text = it.formatJoinPartyNames("\n", PartyNameFormatter.full) + } + } + } + column("Output Party", Transaction::outputParties).setCustomCellFactory { + label { + text = it.formatJoinPartyNames(formatter = PartyNameFormatter.short) + tooltip { + text = it.formatJoinPartyNames("\n", PartyNameFormatter.full) + } + } + } column("Command type", Transaction::commandTypes).cellFormat { text = it.map { it.simpleName }.joinToString() } column("Total value", Transaction::totalValueEquiv).cellFormat { text = "${it.positivity.sign}${AmountFormatter.boring.format(it.amount)}" @@ -154,6 +170,12 @@ class TransactionViewer : CordaView("Transactions") { }) } + private fun ObservableList>>.formatJoinPartyNames(separator: String = "", formatter: Formatter): String { + return flatten().map { + it.value?.legalIdentity?.let { formatter.format(it.name) } + }.filterNotNull().toSet().joinToString(separator) + } + private fun ObservableList>.getParties() = map { it.state.data.participants.map { getModel().lookup(it) } } private fun ObservableList>.toText() = map { it.contract().javaClass.simpleName }.groupBy { it }.map { "${it.key} (${it.value.size})" }.joinToString() @@ -196,7 +218,7 @@ class TransactionViewer : CordaView("Transactions") { signatures.children.addAll(signatureData.map { signature -> val nodeInfo = getModel().lookup(signature) - copyableLabel(nodeInfo.map { "${signature.toStringShort()} (${it?.legalIdentity?.name ?: "???"})" }) + copyableLabel(nodeInfo.map { "${signature.toStringShort()} (${it?.legalIdentity?.let { PartyNameFormatter.short.format(it.name)} ?: "???"})" }) }) } @@ -225,7 +247,7 @@ class TransactionViewer : CordaView("Transactions") { val anonymousIssuer: AnonymousParty = data.amount.token.issuer.party val issuer: AbstractParty = anonymousIssuer.resolveIssuer().value ?: anonymousIssuer // TODO: Anonymous should probably be italicised or similar - label(issuer.nameOrNull() ?: "Anonymous") { + label(issuer.nameOrNull()?.let { PartyNameFormatter.short.format(it) } ?: "Anonymous") { tooltip(anonymousIssuer.owningKey.toBase58String()) } } @@ -233,7 +255,7 @@ class TransactionViewer : CordaView("Transactions") { label("Owner :") { gridpaneConstraints { hAlignment = HPos.RIGHT } } val owner = data.owner val nodeInfo = getModel().lookup(owner) - label(nodeInfo.map { it?.legalIdentity?.name ?: "???" }) { + label(nodeInfo.map { it?.legalIdentity?.let { PartyNameFormatter.short.format(it.name) } ?: "???" }) { tooltip(data.owner.toBase58String()) } } diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/CashViewer.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/CashViewer.kt index 8506f0aa67..523f15bbae 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/CashViewer.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/CashViewer.kt @@ -25,6 +25,7 @@ import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.withoutIssuer import net.corda.core.crypto.AbstractParty import net.corda.explorer.formatters.AmountFormatter +import net.corda.explorer.formatters.PartyNameFormatter import net.corda.explorer.identicon.identicon import net.corda.explorer.identicon.identiconToolTip import net.corda.explorer.model.CordaView @@ -126,7 +127,10 @@ class CashViewer : CordaView("Cash") { } equivLabel.textProperty().bind(equivAmount.map { it.token.currencyCode.toString() }) // TODO: Anonymous should probably be italicised or similar - issuerValueLabel.textProperty().bind(SimpleStringProperty(resolvedIssuer.nameOrNull() ?: "Anonymous")) + issuerValueLabel.textProperty().bind(SimpleStringProperty(resolvedIssuer.nameOrNull()?.let { + PartyNameFormatter.short.format(it) + } ?: "Anonymous")) + issuerValueLabel.apply { tooltip(resolvedIssuer.nameOrNull()?.let { PartyNameFormatter.full.format(it) } ?: "Anonymous") } originatedValueLabel.text = stateRow.originated.toString() amountValueLabel.text = amountFormatter.format(amountNoIssuer) equivValueLabel.textProperty().bind(equivAmount.map { equivFormatter.format(it) }) @@ -230,7 +234,7 @@ class CashViewer : CordaView("Cash") { val node = it.value.value when (node) { // TODO: Anonymous should probably be italicised or similar - is ViewerNode.IssuerNode -> SimpleStringProperty(node.issuer.nameOrNull() ?: "Anonymous") + is ViewerNode.IssuerNode -> SimpleStringProperty(node.issuer.nameOrNull()?.let { PartyNameFormatter.short.format(it) } ?: "Anonymous") is ViewerNode.CurrencyNode -> node.amount.map { it.token.toString() } } } diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt index 91e6d3715c..ab74c1f82b 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt @@ -28,6 +28,7 @@ import net.corda.core.messaging.startFlow import net.corda.core.node.NodeInfo import net.corda.core.serialization.OpaqueBytes import net.corda.core.then +import net.corda.explorer.formatters.PartyNameFormatter import net.corda.explorer.model.CashTransaction import net.corda.explorer.model.IssuerModel import net.corda.explorer.model.ReportingCurrencyModel @@ -167,7 +168,7 @@ class NewTransaction : Fragment() { // Party A textfield always display my identity name, not editable. partyATextField.isEditable = false - partyATextField.textProperty().bind(myIdentity.map { it?.legalIdentity?.name ?: "" }) + partyATextField.textProperty().bind(myIdentity.map { it?.legalIdentity?.let { PartyNameFormatter.short.format(it.name) } ?: "" }) partyALabel.textProperty().bind(transactionTypeCB.valueProperty().map { it?.partyNameA?.let { "$it : " } }) partyATextField.visibleProperty().bind(transactionTypeCB.valueProperty().map { it?.partyNameA }.isNotNull()) @@ -176,17 +177,17 @@ class NewTransaction : Fragment() { partyBChoiceBox.apply { visibleProperty().bind(transactionTypeCB.valueProperty().map { it?.partyNameB }.isNotNull()) items = parties.sorted() - converter = stringConverter { it?.legalIdentity?.name ?: "" } + converter = stringConverter { it?.legalIdentity?.let { PartyNameFormatter.short.format(it.name) } ?: "" } } // Issuer issuerLabel.visibleProperty().bind(transactionTypeCB.valueProperty().isNotNull) issuerChoiceBox.apply { items = issuers.map { it.legalIdentity }.unique().sorted() - converter = stringConverter { it.name } + converter = stringConverter { PartyNameFormatter.short.format(it.name) } visibleProperty().bind(transactionTypeCB.valueProperty().map { it == CashTransaction.Pay }) } issuerTextField.apply { - textProperty().bind(myIdentity.map { it?.legalIdentity?.name }) + textProperty().bind(myIdentity.map { it?.legalIdentity?.let { PartyNameFormatter.short.format(it.name) } }) visibleProperty().bind(transactionTypeCB.valueProperty().map { it == CashTransaction.Issue || it == CashTransaction.Exit }) isEditable = false } diff --git a/tools/explorer/src/main/resources/net/corda/explorer/views/Network.fxml b/tools/explorer/src/main/resources/net/corda/explorer/views/Network.fxml index b8e32c3196..c1469af2ab 100644 --- a/tools/explorer/src/main/resources/net/corda/explorer/views/Network.fxml +++ b/tools/explorer/src/main/resources/net/corda/explorer/views/Network.fxml @@ -19,10 +19,10 @@ - + - +
@@ -31,7 +31,7 @@ - +