mirror of
https://github.com/corda/corda.git
synced 2025-04-11 13:21:26 +00:00
Moved DeclaredField utility to internal and expanded its use
This commit is contained in:
parent
0ccfae252f
commit
b0c299707b
core/src
main/kotlin/net/corda/core
test/kotlin/net/corda/core/crypto
node/src/main/kotlin/net/corda/node
SerialFilter.kt
services
@ -34,7 +34,6 @@ import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipInputStream
|
||||
import java.util.zip.ZipOutputStream
|
||||
import kotlin.concurrent.withLock
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
// TODO: Review by EOY2016 if we ever found these utilities helpful.
|
||||
val Int.bd: BigDecimal get() = BigDecimal(this)
|
||||
@ -338,21 +337,3 @@ fun <T> Class<T>.checkNotUnorderedHashMap() {
|
||||
|
||||
fun Class<*>.requireExternal(msg: String = "Internal class")
|
||||
= require(!name.startsWith("net.corda.node.") && !name.contains(".internal.")) { "$msg: $name" }
|
||||
|
||||
interface DeclaredField<T> {
|
||||
companion object {
|
||||
inline fun <reified T> Any?.declaredField(clazz: KClass<*>, name: String): DeclaredField<T> = declaredField(clazz.java, name)
|
||||
inline fun <reified T> Any.declaredField(name: String): DeclaredField<T> = declaredField(javaClass, name)
|
||||
inline fun <reified T> Any?.declaredField(clazz: Class<*>, name: String): DeclaredField<T> {
|
||||
val javaField = clazz.getDeclaredField(name).apply { isAccessible = true }
|
||||
val receiver = this
|
||||
return object : DeclaredField<T> {
|
||||
override var value
|
||||
get() = javaField.get(receiver) as T
|
||||
set(value) = javaField.set(receiver, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var value: T
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ class CompositeKey private constructor(val threshold: Int, children: List<NodeAn
|
||||
}
|
||||
}
|
||||
|
||||
val children = children.sorted()
|
||||
val children: List<NodeAndWeight> = children.sorted()
|
||||
|
||||
init {
|
||||
// TODO: replace with the more extensive, but slower, checkValidity() test.
|
||||
|
@ -2,11 +2,13 @@ package net.corda.core.internal
|
||||
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.lang.reflect.Field
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
import java.nio.file.*
|
||||
import java.nio.file.attribute.FileAttribute
|
||||
import java.util.stream.Stream
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Allows you to write code like: Paths.get("someDir") / "subdir" / "filename" but using the Paths API to avoid platform
|
||||
@ -43,4 +45,28 @@ inline fun <R> Path.readLines(charset: Charset = UTF_8, block: (Stream<String>)
|
||||
fun Path.readAllLines(charset: Charset = UTF_8): List<String> = Files.readAllLines(this, charset)
|
||||
fun Path.writeLines(lines: Iterable<CharSequence>, charset: Charset = UTF_8, vararg options: OpenOption): Path = Files.write(this, lines, charset, *options)
|
||||
|
||||
fun InputStream.copyTo(target: Path, vararg options: CopyOption): Long = Files.copy(this, target, *options)
|
||||
fun InputStream.copyTo(target: Path, vararg options: CopyOption): Long = Files.copy(this, target, *options)
|
||||
|
||||
/** Returns a [DeclaredField] wrapper around the declared (possibly non-public) static field of the receiver [Class]. */
|
||||
fun <T> Class<*>.staticField(name: String): DeclaredField<T> = DeclaredField(this, name, null)
|
||||
/** Returns a [DeclaredField] wrapper around the declared (possibly non-public) static field of the receiver [KClass]. */
|
||||
fun <T> KClass<*>.staticField(name: String): DeclaredField<T> = DeclaredField(java, name, null)
|
||||
/** Returns a [DeclaredField] wrapper around the declared (possibly non-public) instance field of the receiver object. */
|
||||
fun <T> Any.declaredField(name: String): DeclaredField<T> = DeclaredField(javaClass, name, this)
|
||||
/**
|
||||
* Returns a [DeclaredField] wrapper around the (possibly non-public) instance field of the receiver object, but declared
|
||||
* in its superclass [clazz].
|
||||
*/
|
||||
fun <T> Any.declaredField(clazz: KClass<*>, name: String): DeclaredField<T> = DeclaredField(clazz.java, name, this)
|
||||
|
||||
/**
|
||||
* A simple wrapper around a [Field] object providing type safe read and write access using [value], ignoring the field's
|
||||
* visibility.
|
||||
*/
|
||||
class DeclaredField<T>(clazz: Class<*>, name: String, private val receiver: Any?) {
|
||||
private val javaField = clazz.getDeclaredField(name).apply { isAccessible = true }
|
||||
var value: T
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
get() = javaField.get(receiver) as T
|
||||
set(value) = javaField.set(receiver, value)
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
package net.corda.core.crypto
|
||||
|
||||
import net.corda.core.crypto.composite.CompositeKey
|
||||
import net.corda.core.crypto.composite.CompositeKey.NodeAndWeight
|
||||
import net.corda.core.crypto.composite.CompositeSignature
|
||||
import net.corda.core.crypto.composite.CompositeSignaturesWithKeys
|
||||
import net.corda.core.internal.declaredField
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
@ -233,10 +235,7 @@ class CompositeKeyTests {
|
||||
// We will create a graph cycle between key5 and key3. Key5 has already a reference to key3 (via key4).
|
||||
// To create a cycle, we add a reference (child) from key3 to key5.
|
||||
// Children list is immutable, so reflection is used to inject key5 as an extra NodeAndWeight child of key3.
|
||||
val field = key3.javaClass.getDeclaredField("children")
|
||||
field.isAccessible = true
|
||||
val fixedChildren = key3.children.plus(CompositeKey.NodeAndWeight(key5, 1))
|
||||
field.set(key3, fixedChildren)
|
||||
key3.declaredField<List<NodeAndWeight>>("children").value = key3.children + NodeAndWeight(key5, 1)
|
||||
|
||||
/* A view of the example graph cycle.
|
||||
*
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.node
|
||||
|
||||
import net.corda.core.DeclaredField
|
||||
import net.corda.core.DeclaredField.Companion.declaredField
|
||||
import net.corda.core.internal.DeclaredField
|
||||
import net.corda.core.internal.staticField
|
||||
import net.corda.node.internal.Node
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.Proxy
|
||||
@ -32,8 +32,8 @@ internal object SerialFilter {
|
||||
undecided = statusEnum.getField("UNDECIDED").get(null)
|
||||
rejected = statusEnum.getField("REJECTED").get(null)
|
||||
val configClass = Class.forName("${filterInterface.name}\$Config")
|
||||
serialFilterLock = declaredField<Any>(configClass, "serialFilterLock").value
|
||||
serialFilterField = declaredField(configClass, "serialFilter")
|
||||
serialFilterLock = configClass.staticField<Any>("serialFilterLock").value
|
||||
serialFilterField = configClass.staticField("serialFilter")
|
||||
}
|
||||
|
||||
internal fun install(acceptClass: (Class<*>) -> Boolean) {
|
||||
|
@ -6,19 +6,21 @@ import co.paralleluniverse.fibers.Suspendable
|
||||
import co.paralleluniverse.strands.Strand
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import com.google.common.util.concurrent.SettableFuture
|
||||
import net.corda.core.DeclaredField.Companion.declaredField
|
||||
import net.corda.core.abbreviate
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.flows.*
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.FlowStateMachine
|
||||
import net.corda.core.internal.staticField
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.utilities.*
|
||||
import net.corda.node.services.api.FlowAppAuditEvent
|
||||
import net.corda.node.services.api.FlowPermissionAuditEvent
|
||||
import net.corda.node.services.api.ServiceHubInternal
|
||||
import net.corda.node.utilities.*
|
||||
import net.corda.node.utilities.CordaPersistence
|
||||
import net.corda.node.utilities.DatabaseTransaction
|
||||
import net.corda.node.utilities.DatabaseTransactionManager
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.sql.Connection
|
||||
@ -34,7 +36,7 @@ class FlowStateMachineImpl<R>(override val id: StateMachineRunId,
|
||||
override val flowInitiator: FlowInitiator) : Fiber<Unit>(id.toString(), scheduler), FlowStateMachine<R> {
|
||||
companion object {
|
||||
// Used to work around a small limitation in Quasar.
|
||||
private val QUASAR_UNBLOCKER = declaredField<Any>(Fiber::class, "SERIALIZER_BLOCKER").value
|
||||
private val QUASAR_UNBLOCKER = Fiber::class.staticField<Any>("SERIALIZER_BLOCKER").value
|
||||
|
||||
/**
|
||||
* Return the current [FlowStateMachineImpl] or null if executing outside of one.
|
||||
|
@ -5,6 +5,7 @@ import co.paralleluniverse.fibers.FiberExecutorScheduler
|
||||
import co.paralleluniverse.io.serialization.kryo.KryoSerializer
|
||||
import co.paralleluniverse.strands.Strand
|
||||
import com.codahale.metrics.Gauge
|
||||
import com.esotericsoftware.kryo.ClassResolver
|
||||
import com.esotericsoftware.kryo.Kryo
|
||||
import com.esotericsoftware.kryo.KryoException
|
||||
import com.esotericsoftware.kryo.Serializer
|
||||
@ -24,6 +25,7 @@ import net.corda.core.flows.FlowInitiator
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.StateMachineRunId
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.declaredField
|
||||
import net.corda.core.messaging.DataFeed
|
||||
import net.corda.core.serialization.*
|
||||
import net.corda.core.then
|
||||
@ -37,7 +39,10 @@ import net.corda.node.services.api.CheckpointStorage
|
||||
import net.corda.node.services.api.ServiceHubInternal
|
||||
import net.corda.node.services.messaging.ReceivedMessage
|
||||
import net.corda.node.services.messaging.TopicSession
|
||||
import net.corda.node.utilities.*
|
||||
import net.corda.node.utilities.AffinityExecutor
|
||||
import net.corda.node.utilities.CordaPersistence
|
||||
import net.corda.node.utilities.bufferUntilDatabaseCommit
|
||||
import net.corda.node.utilities.wrapWithDatabaseTransaction
|
||||
import org.apache.activemq.artemis.utils.ReusableLatch
|
||||
import org.slf4j.Logger
|
||||
import rx.Observable
|
||||
@ -83,10 +88,9 @@ class StateMachineManager(val serviceHub: ServiceHubInternal,
|
||||
private val quasarKryoPool = KryoPool.Builder {
|
||||
val serializer = Fiber.getFiberSerializer(false) as KryoSerializer
|
||||
val classResolver = makeNoWhitelistClassResolver().apply { setKryo(serializer.kryo) }
|
||||
// TODO The ClassResolver can only be set in the Kryo constructor and Quasar doesn't provide us with a way of doing that
|
||||
val field = Kryo::class.java.getDeclaredField("classResolver").apply { isAccessible = true }
|
||||
serializer.kryo.apply {
|
||||
field.set(this, classResolver)
|
||||
// TODO The ClassResolver can only be set in the Kryo constructor and Quasar doesn't provide us with a way of doing that
|
||||
declaredField<ClassResolver>(Kryo::class, "classResolver").value = classResolver
|
||||
DefaultKryoCustomizer.customize(this)
|
||||
addDefaultSerializer(AutoCloseable::class.java, AutoCloseableSerialisationDetector)
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import bftsmart.tom.core.messages.TOMMessage
|
||||
import bftsmart.tom.server.defaultservices.DefaultRecoverable
|
||||
import bftsmart.tom.server.defaultservices.DefaultReplier
|
||||
import bftsmart.tom.util.Extractor
|
||||
import net.corda.core.DeclaredField.Companion.declaredField
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TimeWindow
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
@ -21,6 +20,7 @@ import net.corda.core.crypto.sign
|
||||
import net.corda.core.flows.NotaryError
|
||||
import net.corda.core.flows.NotaryException
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.declaredField
|
||||
import net.corda.core.node.services.TimeWindowChecker
|
||||
import net.corda.core.node.services.UniquenessProvider
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
|
Loading…
x
Reference in New Issue
Block a user