mirror of
https://github.com/corda/corda.git
synced 2024-12-21 05:53:23 +00:00
Merge branch 'master' into feature/CID-878-non_party_flow_sessions
# Conflicts: # core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt
This commit is contained in:
commit
f0f05df9f4
10
.idea/compiler.xml
generated
10
.idea/compiler.xml
generated
@ -37,6 +37,8 @@
|
|||||||
<module name="cliutils_test" target="1.8" />
|
<module name="cliutils_test" target="1.8" />
|
||||||
<module name="common-configuration-parsing_main" target="1.8" />
|
<module name="common-configuration-parsing_main" target="1.8" />
|
||||||
<module name="common-configuration-parsing_test" target="1.8" />
|
<module name="common-configuration-parsing_test" target="1.8" />
|
||||||
|
<module name="common-logging_main" target="1.8" />
|
||||||
|
<module name="common-logging_test" target="1.8" />
|
||||||
<module name="common-validation_main" target="1.8" />
|
<module name="common-validation_main" target="1.8" />
|
||||||
<module name="common-validation_test" target="1.8" />
|
<module name="common-validation_test" target="1.8" />
|
||||||
<module name="confidential-identities_main" target="1.8" />
|
<module name="confidential-identities_main" target="1.8" />
|
||||||
@ -177,6 +179,8 @@
|
|||||||
<module name="net.corda_buildSrc_test" target="1.8" />
|
<module name="net.corda_buildSrc_test" target="1.8" />
|
||||||
<module name="net.corda_canonicalizer_main" target="1.8" />
|
<module name="net.corda_canonicalizer_main" target="1.8" />
|
||||||
<module name="net.corda_canonicalizer_test" target="1.8" />
|
<module name="net.corda_canonicalizer_test" target="1.8" />
|
||||||
|
<module name="netparams_main" target="1.8" />
|
||||||
|
<module name="netparams_test" target="1.8" />
|
||||||
<module name="network-bootstrapper_main" target="1.8" />
|
<module name="network-bootstrapper_main" target="1.8" />
|
||||||
<module name="network-bootstrapper_test" target="1.8" />
|
<module name="network-bootstrapper_test" target="1.8" />
|
||||||
<module name="network-verifier-contracts_main" target="1.8" />
|
<module name="network-verifier-contracts_main" target="1.8" />
|
||||||
@ -189,8 +193,8 @@
|
|||||||
<module name="network-visualiser_test" target="1.8" />
|
<module name="network-visualiser_test" target="1.8" />
|
||||||
<module name="node-api_main" target="1.8" />
|
<module name="node-api_main" target="1.8" />
|
||||||
<module name="node-api_test" target="1.8" />
|
<module name="node-api_test" target="1.8" />
|
||||||
<module name="node-capsule_main" target="1.6" />
|
<module name="node-capsule_main" target="1.8" />
|
||||||
<module name="node-capsule_test" target="1.6" />
|
<module name="node-capsule_test" target="1.8" />
|
||||||
<module name="node-driver_integrationTest" target="1.8" />
|
<module name="node-driver_integrationTest" target="1.8" />
|
||||||
<module name="node-driver_main" target="1.8" />
|
<module name="node-driver_main" target="1.8" />
|
||||||
<module name="node-driver_test" target="1.8" />
|
<module name="node-driver_test" target="1.8" />
|
||||||
@ -200,6 +204,8 @@
|
|||||||
<module name="node_main" target="1.8" />
|
<module name="node_main" target="1.8" />
|
||||||
<module name="node_smokeTest" target="1.8" />
|
<module name="node_smokeTest" target="1.8" />
|
||||||
<module name="node_test" target="1.8" />
|
<module name="node_test" target="1.8" />
|
||||||
|
<module name="nodeinfo_main" target="1.8" />
|
||||||
|
<module name="nodeinfo_test" target="1.8" />
|
||||||
<module name="notary-bft-smart_main" target="1.8" />
|
<module name="notary-bft-smart_main" target="1.8" />
|
||||||
<module name="notary-bft-smart_test" target="1.8" />
|
<module name="notary-bft-smart_test" target="1.8" />
|
||||||
<module name="notary-demo-contracts_main" target="1.8" />
|
<module name="notary-demo-contracts_main" target="1.8" />
|
||||||
|
21
SECURITY.md
Normal file
21
SECURITY.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
Vulnerabilities in Corda can be reported by following the Corda responsible disclosure policy:
|
||||||
|
|
||||||
|
https://www.corda.net/participate/security.html
|
||||||
|
|
||||||
|
## Security Advisories
|
||||||
|
|
||||||
|
Security announcements affecting Corda will be published on the Corda mailing list. People can subscribe to corda-announce@groups.io to receive security updates when they are made available.
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
Security updates are made for the latest version of Corda.
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
| ------- | ------------------ |
|
||||||
|
| 4.x | :white_check_mark: |
|
||||||
|
| 3.x | :x: |
|
||||||
|
| < 3 | :x: |
|
67
build.gradle
67
build.gradle
@ -15,6 +15,26 @@ buildscript {
|
|||||||
|
|
||||||
ext.quasar_group = 'co.paralleluniverse'
|
ext.quasar_group = 'co.paralleluniverse'
|
||||||
ext.quasar_version = constants.getProperty("quasarVersion")
|
ext.quasar_version = constants.getProperty("quasarVersion")
|
||||||
|
ext.quasar_exclusions = [
|
||||||
|
'co.paralleluniverse**',
|
||||||
|
'groovy**',
|
||||||
|
'com.esotericsoftware.**',
|
||||||
|
'jdk**',
|
||||||
|
'junit**',
|
||||||
|
'kotlin**',
|
||||||
|
'net.rubygrapefruit.**',
|
||||||
|
'org.gradle.**',
|
||||||
|
'org.apache.**',
|
||||||
|
'org.jacoco.**',
|
||||||
|
'org.junit**',
|
||||||
|
'org.slf4j**',
|
||||||
|
'worker.org.gradle.**',
|
||||||
|
'com.nhaarman.mockito_kotlin**',
|
||||||
|
'org.assertj**',
|
||||||
|
'org.hamcrest**',
|
||||||
|
'org.mockito**',
|
||||||
|
'org.opentest4j**'
|
||||||
|
]
|
||||||
|
|
||||||
// gradle-capsule-plugin:1.0.2 contains capsule:1.0.1 by default.
|
// gradle-capsule-plugin:1.0.2 contains capsule:1.0.1 by default.
|
||||||
// We must configure it manually to use the latest capsule version.
|
// We must configure it manually to use the latest capsule version.
|
||||||
@ -22,10 +42,12 @@ buildscript {
|
|||||||
|
|
||||||
ext.asm_version = '5.0.4'
|
ext.asm_version = '5.0.4'
|
||||||
ext.artemis_version = '2.6.2'
|
ext.artemis_version = '2.6.2'
|
||||||
ext.jackson_version = '2.9.8'
|
// upgrade Jackson only when corda is using kotlin 1.3.10
|
||||||
ext.jetty_version = '9.4.7.v20170914'
|
ext.jackson_version = '2.9.5'
|
||||||
|
ext.jetty_version = '9.4.18.v20190429'
|
||||||
ext.jersey_version = '2.25'
|
ext.jersey_version = '2.25'
|
||||||
ext.assertj_version = '3.8.0'
|
ext.servlet_version = '4.0.1'
|
||||||
|
ext.assertj_version = '3.12.2'
|
||||||
ext.slf4j_version = '1.7.25'
|
ext.slf4j_version = '1.7.25'
|
||||||
ext.log4j_version = '2.9.1'
|
ext.log4j_version = '2.9.1'
|
||||||
ext.bouncycastle_version = constants.getProperty("bouncycastleVersion")
|
ext.bouncycastle_version = constants.getProperty("bouncycastleVersion")
|
||||||
@ -34,14 +56,22 @@ buildscript {
|
|||||||
ext.disruptor_version = constants.getProperty("disruptorVersion")
|
ext.disruptor_version = constants.getProperty("disruptorVersion")
|
||||||
ext.metrics_version = constants.getProperty("metricsVersion")
|
ext.metrics_version = constants.getProperty("metricsVersion")
|
||||||
ext.metrics_new_relic_version = constants.getProperty("metricsNewRelicVersion")
|
ext.metrics_new_relic_version = constants.getProperty("metricsNewRelicVersion")
|
||||||
ext.okhttp_version = '3.5.0'
|
ext.okhttp_version = '3.14.1'
|
||||||
ext.netty_version = '4.1.22.Final'
|
ext.netty_version = '4.1.22.Final'
|
||||||
ext.typesafe_config_version = constants.getProperty("typesafeConfigVersion")
|
ext.typesafe_config_version = constants.getProperty("typesafeConfigVersion")
|
||||||
ext.fileupload_version = '1.3.3'
|
ext.fileupload_version = '1.4'
|
||||||
|
// Legacy JUnit 4 version
|
||||||
ext.junit_version = '4.12'
|
ext.junit_version = '4.12'
|
||||||
|
// Need this version to access classpath scanning error handling fix -
|
||||||
|
// see https://github.com/junit-team/junit5/commit/389de48c2a18c5a93a7203ef424aa47a8a835a74
|
||||||
|
// Upgrade to 5.5.x when GA release is available.
|
||||||
|
ext.junit_vintage_version = '5.5.0-RC1'
|
||||||
|
ext.junit_jupiter_version = '5.5.0-RC1'
|
||||||
|
ext.junit_platform_version = '1.5.0-RC1'
|
||||||
|
// TODO Update this to the latest version when hibernate is updated
|
||||||
ext.mockito_version = '2.18.3'
|
ext.mockito_version = '2.18.3'
|
||||||
ext.mockito_kotlin_version = '1.5.0'
|
ext.mockito_kotlin_version = '1.6.0'
|
||||||
ext.hamkrest_version = '1.4.2.2'
|
ext.hamkrest_version = '1.7.0.0'
|
||||||
ext.jopt_simple_version = '5.0.2'
|
ext.jopt_simple_version = '5.0.2'
|
||||||
ext.jansi_version = '1.14'
|
ext.jansi_version = '1.14'
|
||||||
ext.hibernate_version = '5.3.10.Final'
|
ext.hibernate_version = '5.3.10.Final'
|
||||||
@ -50,7 +80,7 @@ buildscript {
|
|||||||
ext.rxjava_version = '1.3.8'
|
ext.rxjava_version = '1.3.8'
|
||||||
ext.dokka_version = '0.9.17'
|
ext.dokka_version = '0.9.17'
|
||||||
ext.eddsa_version = '0.2.0'
|
ext.eddsa_version = '0.2.0'
|
||||||
ext.dependency_checker_version = '4.0.0'
|
ext.dependency_checker_version = '4.0.2'
|
||||||
ext.commons_collections_version = '4.1'
|
ext.commons_collections_version = '4.1'
|
||||||
ext.beanutils_version = '1.9.3'
|
ext.beanutils_version = '1.9.3'
|
||||||
ext.crash_version = '810d2b774b85d4938be01b9b65e29e4fddbc450b'
|
ext.crash_version = '810d2b774b85d4938be01b9b65e29e4fddbc450b'
|
||||||
@ -61,8 +91,8 @@ buildscript {
|
|||||||
ext.liquibase_version = '3.5.5'
|
ext.liquibase_version = '3.5.5'
|
||||||
ext.artifactory_contextUrl = 'https://ci-artifactory.corda.r3cev.com/artifactory'
|
ext.artifactory_contextUrl = 'https://ci-artifactory.corda.r3cev.com/artifactory'
|
||||||
ext.snake_yaml_version = constants.getProperty('snakeYamlVersion')
|
ext.snake_yaml_version = constants.getProperty('snakeYamlVersion')
|
||||||
ext.docker_compose_rule_version = '0.33.0'
|
ext.docker_compose_rule_version = '0.35.0'
|
||||||
ext.selenium_version = '3.8.1'
|
ext.selenium_version = '3.141.59'
|
||||||
ext.ghostdriver_version = '2.1.0'
|
ext.ghostdriver_version = '2.1.0'
|
||||||
ext.eaagentloader_version = '1.0.3'
|
ext.eaagentloader_version = '1.0.3'
|
||||||
ext.proguard_version = constants.getProperty('proguardVersion')
|
ext.proguard_version = constants.getProperty('proguardVersion')
|
||||||
@ -111,18 +141,16 @@ buildscript {
|
|||||||
classpath "net.i2p.crypto:eddsa:$eddsa_version" // Needed for ServiceIdentityGenerator in the build environment.
|
classpath "net.i2p.crypto:eddsa:$eddsa_version" // Needed for ServiceIdentityGenerator in the build environment.
|
||||||
classpath "org.owasp:dependency-check-gradle:${dependency_checker_version}"
|
classpath "org.owasp:dependency-check-gradle:${dependency_checker_version}"
|
||||||
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:$artifactory_plugin_version"
|
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:$artifactory_plugin_version"
|
||||||
|
// Capsule gradle plugin forked and maintained locally to support Gradle 5.x
|
||||||
|
// See https://github.com/corda/gradle-capsule-plugin
|
||||||
|
classpath "us.kirchmeier:gradle-capsule-plugin:1.0.4_r3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
// TODO The capsule plugin requires the newer DSL plugin block.It would be nice if we could unify all the plugins into one style,
|
|
||||||
// but the DSL has some restrictions e.g can't be used on the allprojects section. So we should revisit this if there are improvements in Gradle.
|
|
||||||
// Version 1.0.2 of this plugin uses capsule:1.0.1 by default.
|
|
||||||
id 'us.kirchmeier.capsule' version '1.0.2' apply false
|
|
||||||
|
|
||||||
// Add the shadow plugin to the plugins classpath for the entire project.
|
// Add the shadow plugin to the plugins classpath for the entire project.
|
||||||
id 'com.github.johnrengelman.shadow' version '2.0.4' apply false
|
id 'com.github.johnrengelman.shadow' version '2.0.4' apply false
|
||||||
id "com.gradle.build-scan" version "1.16"
|
id "com.gradle.build-scan" version "2.2.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
@ -208,6 +236,8 @@ allprojects {
|
|||||||
// Prevent the project from creating temporary files outside of the build directory.
|
// Prevent the project from creating temporary files outside of the build directory.
|
||||||
systemProperty 'java.io.tmpdir', buildDir.absolutePath
|
systemProperty 'java.io.tmpdir', buildDir.absolutePath
|
||||||
|
|
||||||
|
maxHeapSize = "1g"
|
||||||
|
|
||||||
if (project.hasProperty('test.parallel') && project.property('test.parallel').toBoolean()) {
|
if (project.hasProperty('test.parallel') && project.property('test.parallel').toBoolean()) {
|
||||||
maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) as int ?: 1
|
maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) as int ?: 1
|
||||||
}
|
}
|
||||||
@ -366,6 +396,7 @@ bintrayConfig {
|
|||||||
'corda-node-api',
|
'corda-node-api',
|
||||||
'corda-test-common',
|
'corda-test-common',
|
||||||
'corda-test-utils',
|
'corda-test-utils',
|
||||||
|
'corda-test-db',
|
||||||
'corda-jackson',
|
'corda-jackson',
|
||||||
'corda-webserver-impl',
|
'corda-webserver-impl',
|
||||||
'corda-webserver',
|
'corda-webserver',
|
||||||
@ -461,8 +492,10 @@ if (file('corda-docs-only-build').exists() || (System.getenv('CORDA_DOCS_ONLY_BU
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
wrapper {
|
wrapper {
|
||||||
gradleVersion = "4.10.1"
|
gradleVersion = "5.4.1"
|
||||||
distributionType = Wrapper.DistributionType.ALL
|
distributionType = Wrapper.DistributionType.ALL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,8 +18,16 @@ dependencies {
|
|||||||
|
|
||||||
testCompile project(':test-utils')
|
testCompile project(':test-utils')
|
||||||
testCompile project(path: ':core', configuration: 'testArtifacts')
|
testCompile project(path: ':core', configuration: 'testArtifacts')
|
||||||
|
|
||||||
|
testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}"
|
||||||
|
testImplementation "junit:junit:$junit_version"
|
||||||
|
|
||||||
|
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
|
||||||
|
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_jupiter_version}"
|
||||||
|
testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
|
||||||
|
|
||||||
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
||||||
testCompile "junit:junit:$junit_version"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
|
@ -239,7 +239,8 @@ open class StringToMethodCallParser<in T : Any> @JvmOverloads constructor(
|
|||||||
/** Returns a string-to-string map of commands to a string describing available parameter types. */
|
/** Returns a string-to-string map of commands to a string describing available parameter types. */
|
||||||
val availableCommands: Map<String, String>
|
val availableCommands: Map<String, String>
|
||||||
get() {
|
get() {
|
||||||
return methodMap.entries().map { (name, args) ->
|
return methodMap.entries().map { entry ->
|
||||||
|
val (name, args) = entry // TODO: Kotlin 1.1
|
||||||
val argStr = if (args.parameterCount == 0) "" else {
|
val argStr = if (args.parameterCount == 0) "" else {
|
||||||
val paramNames = methodParamNames[name]!!
|
val paramNames = methodParamNames[name]!!
|
||||||
val typeNames = args.parameters.map { it.type.simpleName }
|
val typeNames = args.parameters.map { it.type.simpleName }
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
package net.corda.client.jackson.internal
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.Module
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Should be implemented by CorDapps who wish to declare custom serializers.
|
|
||||||
* Classes of this type will be autodiscovered and registered.
|
|
||||||
*/
|
|
||||||
interface CustomShellSerializationFactory {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The returned [Module] will be registered automatically with the interactive shell.
|
|
||||||
*/
|
|
||||||
fun createJacksonModule(): Module
|
|
||||||
}
|
|
@ -697,7 +697,7 @@ class JacksonSupportTest(@Suppress("unused") private val name: String, factory:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun JsonNode.assertHasOnlyFields(vararg fieldNames: String): List<JsonNode> {
|
private fun JsonNode.assertHasOnlyFields(vararg fieldNames: String): List<JsonNode> {
|
||||||
assertThat(fieldNames()).containsOnly(*fieldNames)
|
assertThat(fieldNames()).toIterable().containsOnly(*fieldNames)
|
||||||
return fieldNames.map { this[it] }
|
return fieldNames.map { this[it] }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,13 @@ dependencies {
|
|||||||
compile "org.apache.activemq:artemis-core-client:${artemis_version}"
|
compile "org.apache.activemq:artemis-core-client:${artemis_version}"
|
||||||
|
|
||||||
// Unit testing helpers.
|
// Unit testing helpers.
|
||||||
testCompile "junit:junit:$junit_version"
|
testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}"
|
||||||
|
testImplementation "junit:junit:$junit_version"
|
||||||
|
|
||||||
|
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
|
||||||
|
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_jupiter_version}"
|
||||||
|
testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
|
||||||
|
|
||||||
testCompile "org.assertj:assertj-core:${assertj_version}"
|
testCompile "org.assertj:assertj-core:${assertj_version}"
|
||||||
|
|
||||||
testCompile project(':test-utils')
|
testCompile project(':test-utils')
|
||||||
|
@ -13,8 +13,14 @@ dependencies {
|
|||||||
compile project(':finance:workflows')
|
compile project(':finance:workflows')
|
||||||
compile project(':finance:contracts')
|
compile project(':finance:contracts')
|
||||||
|
|
||||||
|
testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}"
|
||||||
|
testImplementation "junit:junit:$junit_version"
|
||||||
|
|
||||||
|
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
|
||||||
|
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_jupiter_version}"
|
||||||
|
testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
|
||||||
|
|
||||||
// Unit testing helpers.
|
// Unit testing helpers.
|
||||||
testCompile "junit:junit:$junit_version"
|
|
||||||
testCompile "org.assertj:assertj-core:${assertj_version}"
|
testCompile "org.assertj:assertj-core:${assertj_version}"
|
||||||
|
|
||||||
testCompile project(':test-utils')
|
testCompile project(':test-utils')
|
||||||
|
@ -9,10 +9,10 @@ description 'Corda client RPC modules'
|
|||||||
//noinspection GroovyAssignabilityCheck
|
//noinspection GroovyAssignabilityCheck
|
||||||
configurations {
|
configurations {
|
||||||
integrationTestCompile.extendsFrom testCompile
|
integrationTestCompile.extendsFrom testCompile
|
||||||
integrationTestRuntime.extendsFrom testRuntime
|
integrationTestRuntimeOnly.extendsFrom testRuntimeOnly
|
||||||
|
|
||||||
smokeTestCompile.extendsFrom compile
|
smokeTestCompile.extendsFrom compile
|
||||||
smokeTestRuntime.extendsFrom runtime
|
smokeTestRuntimeOnly.extendsFrom runtimeOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
compileKotlin {
|
compileKotlin {
|
||||||
@ -74,9 +74,13 @@ dependencies {
|
|||||||
// For caches rather than guava
|
// For caches rather than guava
|
||||||
compile "com.github.ben-manes.caffeine:caffeine:$caffeine_version"
|
compile "com.github.ben-manes.caffeine:caffeine:$caffeine_version"
|
||||||
|
|
||||||
|
testImplementation "junit:junit:$junit_version"
|
||||||
|
|
||||||
|
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
|
||||||
|
testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
|
||||||
|
|
||||||
// Unit testing helpers.
|
// Unit testing helpers.
|
||||||
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
||||||
testCompile "junit:junit:$junit_version"
|
|
||||||
testCompile "org.assertj:assertj-core:${assertj_version}"
|
testCompile "org.assertj:assertj-core:${assertj_version}"
|
||||||
|
|
||||||
testCompile project(':node-driver')
|
testCompile project(':node-driver')
|
||||||
@ -91,7 +95,9 @@ dependencies {
|
|||||||
smokeTestCompile "org.apache.logging.log4j:log4j-core:$log4j_version"
|
smokeTestCompile "org.apache.logging.log4j:log4j-core:$log4j_version"
|
||||||
smokeTestCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
smokeTestCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
||||||
smokeTestCompile "org.assertj:assertj-core:${assertj_version}"
|
smokeTestCompile "org.assertj:assertj-core:${assertj_version}"
|
||||||
smokeTestCompile "junit:junit:$junit_version"
|
smokeTestImplementation "junit:junit:$junit_version"
|
||||||
|
smokeTestRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
|
||||||
|
smokeTestRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
|
||||||
}
|
}
|
||||||
|
|
||||||
task integrationTest(type: Test) {
|
task integrationTest(type: Test) {
|
||||||
|
@ -21,6 +21,7 @@ import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration
|
|||||||
import org.apache.activemq.artemis.api.core.SimpleString
|
import org.apache.activemq.artemis.api.core.SimpleString
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Assert.*
|
import org.junit.Assert.*
|
||||||
|
import org.junit.Ignore
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
@ -498,6 +499,7 @@ class RPCStabilityTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore // TODO: This is ignored because Artemis slow consumers are broken. I'm not deleting it in case we can get the feature fixed.
|
||||||
fun `slow consumers are kicked`() {
|
fun `slow consumers are kicked`() {
|
||||||
rpcDriver {
|
rpcDriver {
|
||||||
val server = startRpcServer(maxBufferedBytesPerClient = 10 * 1024 * 1024, ops = SlowConsumerRPCOpsImpl()).get()
|
val server = startRpcServer(maxBufferedBytesPerClient = 10 * 1024 * 1024, ops = SlowConsumerRPCOpsImpl()).get()
|
||||||
@ -508,7 +510,7 @@ class RPCStabilityTests {
|
|||||||
session.createTemporaryQueue(myQueue, ActiveMQDefaultConfiguration.getDefaultRoutingType(), myQueue)
|
session.createTemporaryQueue(myQueue, ActiveMQDefaultConfiguration.getDefaultRoutingType(), myQueue)
|
||||||
val consumer = session.createConsumer(myQueue, null, -1, -1, false)
|
val consumer = session.createConsumer(myQueue, null, -1, -1, false)
|
||||||
consumer.setMessageHandler {
|
consumer.setMessageHandler {
|
||||||
Thread.sleep(50) // 5x slower than the server producer
|
Thread.sleep(5000) // Needs to be slower than one per second to get kicked.
|
||||||
it.acknowledge()
|
it.acknowledge()
|
||||||
}
|
}
|
||||||
val producer = session.createProducer(RPCApi.RPC_SERVER_QUEUE_NAME)
|
val producer = session.createProducer(RPCApi.RPC_SERVER_QUEUE_NAME)
|
||||||
@ -520,7 +522,7 @@ class RPCStabilityTests {
|
|||||||
val request = RPCApi.ClientToServer.RpcRequest(
|
val request = RPCApi.ClientToServer.RpcRequest(
|
||||||
clientAddress = SimpleString(myQueue),
|
clientAddress = SimpleString(myQueue),
|
||||||
methodName = SlowConsumerRPCOps::streamAtInterval.name,
|
methodName = SlowConsumerRPCOps::streamAtInterval.name,
|
||||||
serialisedArguments = listOf(10.millis, 123456).serialize(context = SerializationDefaults.RPC_SERVER_CONTEXT),
|
serialisedArguments = listOf(100.millis, 1234).serialize(context = SerializationDefaults.RPC_SERVER_CONTEXT),
|
||||||
replyId = Trace.InvocationId.newInstance(),
|
replyId = Trace.InvocationId.newInstance(),
|
||||||
sessionId = Trace.SessionId.newInstance()
|
sessionId = Trace.SessionId.newInstance()
|
||||||
)
|
)
|
||||||
@ -529,7 +531,7 @@ class RPCStabilityTests {
|
|||||||
producer.send(message)
|
producer.send(message)
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
// We are consuming slower than the server is producing, so we should be kicked after a while
|
// We are consuming slower than the server is producing, so we should be kicked after a while if slow consumers are enabled.
|
||||||
pollUntilClientNumber(server, 0)
|
pollUntilClientNumber(server, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ import net.corda.serialization.internal.amqp.SerializationFactoryCacheKey
|
|||||||
import net.corda.serialization.internal.amqp.SerializerFactory
|
import net.corda.serialization.internal.amqp.SerializerFactory
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.ServiceLoader
|
import java.util.ServiceLoader
|
||||||
import java.net.URLClassLoader
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is essentially just a wrapper for an RPCConnection<CordaRPCOps> and can be treated identically.
|
* This class is essentially just a wrapper for an RPCConnection<CordaRPCOps> and can be treated identically.
|
||||||
@ -300,14 +299,11 @@ class CordaRPCClient private constructor(
|
|||||||
try {
|
try {
|
||||||
val cache = Caffeine.newBuilder().maximumSize(128).build<SerializationFactoryCacheKey, SerializerFactory>().asMap()
|
val cache = Caffeine.newBuilder().maximumSize(128).build<SerializationFactoryCacheKey, SerializerFactory>().asMap()
|
||||||
|
|
||||||
// If the client has provided a classloader, the associated classpath is checked for available custom serializers and serialization whitelists.
|
// If the client has explicitly provided a classloader use this one to scan for custom serializers, otherwise use the current one.
|
||||||
if (classLoader != null) {
|
val serializationClassLoader = this.classLoader ?: this.javaClass.classLoader
|
||||||
val customSerializers = createInstancesOfClassesImplementing(classLoader, SerializationCustomSerializer::class.java)
|
val customSerializers = createInstancesOfClassesImplementing(serializationClassLoader, SerializationCustomSerializer::class.java)
|
||||||
val serializationWhitelists = ServiceLoader.load(SerializationWhitelist::class.java, classLoader).toSet()
|
val serializationWhitelists = ServiceLoader.load(SerializationWhitelist::class.java, serializationClassLoader).toSet()
|
||||||
AMQPClientSerializationScheme.initialiseSerialization(classLoader, customSerializers, serializationWhitelists, cache)
|
AMQPClientSerializationScheme.initialiseSerialization(serializationClassLoader, customSerializers, serializationWhitelists, cache)
|
||||||
} else {
|
|
||||||
AMQPClientSerializationScheme.initialiseSerialization(classLoader, serializerFactoriesForContexts = cache)
|
|
||||||
}
|
|
||||||
} catch (e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
// Race e.g. two of these constructed in parallel, ignore.
|
// Race e.g. two of these constructed in parallel, ignore.
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,14 @@ dependencies {
|
|||||||
|
|
||||||
compile project(":common-validation")
|
compile project(":common-validation")
|
||||||
|
|
||||||
|
testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}"
|
||||||
|
testImplementation "junit:junit:$junit_version"
|
||||||
|
|
||||||
|
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
|
||||||
|
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_jupiter_version}"
|
||||||
|
testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
|
||||||
|
|
||||||
testCompile group: "org.jetbrains.kotlin", name: "kotlin-test", version: kotlin_version
|
testCompile group: "org.jetbrains.kotlin", name: "kotlin-test", version: kotlin_version
|
||||||
testCompile group: "junit", name: "junit", version: junit_version
|
|
||||||
testCompile group: "org.assertj", name: "assertj-core", version: assertj_version
|
testCompile group: "org.assertj", name: "assertj-core", version: assertj_version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
apply plugin: 'kotlin'
|
import org.apache.tools.ant.filters.ReplaceTokens
|
||||||
|
|
||||||
|
apply plugin: 'kotlin'
|
||||||
apply plugin: 'net.corda.plugins.publish-utils'
|
apply plugin: 'net.corda.plugins.publish-utils'
|
||||||
apply plugin: 'com.jfrog.artifactory'
|
apply plugin: 'com.jfrog.artifactory'
|
||||||
|
|
||||||
@ -8,15 +9,23 @@ dependencies {
|
|||||||
compile group: "org.jetbrains.kotlin", name: "kotlin-reflect", version: kotlin_version
|
compile group: "org.jetbrains.kotlin", name: "kotlin-reflect", version: kotlin_version
|
||||||
|
|
||||||
compile group: "com.typesafe", name: "config", version: typesafe_config_version
|
compile group: "com.typesafe", name: "config", version: typesafe_config_version
|
||||||
compile "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
|
|
||||||
|
|
||||||
|
// Log4J: logging framework
|
||||||
|
compile "org.apache.logging.log4j:log4j-core:$log4j_version"
|
||||||
|
|
||||||
compile "com.jcabi:jcabi-manifests:$jcabi_manifests_version"
|
compile "com.jcabi:jcabi-manifests:$jcabi_manifests_version"
|
||||||
|
|
||||||
|
|
||||||
testCompile project(":test-utils")
|
testCompile project(":test-utils")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
task generateSource(type: Copy) {
|
||||||
|
from 'src/main/template'
|
||||||
|
filter(ReplaceTokens, tokens: [corda_release_version: corda_release_version])
|
||||||
|
into 'src/main'
|
||||||
|
}
|
||||||
|
compileKotlin.dependsOn generateSource
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
baseName 'corda-common-logging'
|
baseName 'corda-common-logging'
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
@file:JvmName("Constants")
|
||||||
|
|
||||||
|
package net.corda.common.logging
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constants in this file are generated by gradle
|
||||||
|
* to change this file, edit src/main/template/kotlin/net/corda/common/logging/Constants.kt
|
||||||
|
* the generated file does not need to be committed to source control (originally added to source control for ease of use)
|
||||||
|
*/
|
||||||
|
|
||||||
|
internal const val CURRENT_MAJOR_RELEASE = "5.0-SNAPSHOT"
|
@ -5,7 +5,6 @@ import com.jcabi.manifests.Manifests
|
|||||||
class CordaVersion {
|
class CordaVersion {
|
||||||
companion object {
|
companion object {
|
||||||
private const val UNKNOWN = "Unknown"
|
private const val UNKNOWN = "Unknown"
|
||||||
const val current_major_release = "4.0-SNAPSHOT"
|
|
||||||
const val platformEditionCode = "OS"
|
const val platformEditionCode = "OS"
|
||||||
|
|
||||||
private fun manifestValue(name: String): String? = if (Manifests.exists(name)) Manifests.read(name) else null
|
private fun manifestValue(name: String): String? = if (Manifests.exists(name)) Manifests.read(name) else null
|
||||||
@ -15,7 +14,7 @@ class CordaVersion {
|
|||||||
val vendor: String by lazy { manifestValue("Corda-Vendor") ?: UNKNOWN }
|
val vendor: String by lazy { manifestValue("Corda-Vendor") ?: UNKNOWN }
|
||||||
val platformVersion: Int by lazy { manifestValue("Corda-Platform-Version")?.toInt() ?: 1 }
|
val platformVersion: Int by lazy { manifestValue("Corda-Platform-Version")?.toInt() ?: 1 }
|
||||||
|
|
||||||
internal val semanticVersion: String by lazy { if(releaseVersion == UNKNOWN) current_major_release else releaseVersion }
|
internal val semanticVersion: String by lazy { if(releaseVersion == UNKNOWN) CURRENT_MAJOR_RELEASE else releaseVersion }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getVersion(): Array<String> {
|
fun getVersion(): Array<String> {
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
@file:JvmName("Constants")
|
||||||
|
|
||||||
|
package net.corda.common.logging
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constants in this file are generated by gradle
|
||||||
|
* to change this file, edit src/main/template/kotlin/net/corda/common/logging/Constants.kt
|
||||||
|
* the generated file does not need to be committed to source control (originally added to source control for ease of use)
|
||||||
|
*/
|
||||||
|
|
||||||
|
internal const val CURRENT_MAJOR_RELEASE = "@corda_release_version@"
|
@ -12,7 +12,12 @@ dependencies {
|
|||||||
cordaCompile project(':core')
|
cordaCompile project(':core')
|
||||||
|
|
||||||
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
||||||
testCompile "junit:junit:$junit_version"
|
testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}"
|
||||||
|
testImplementation "junit:junit:$junit_version"
|
||||||
|
|
||||||
|
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
|
||||||
|
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_jupiter_version}"
|
||||||
|
testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
|
||||||
|
|
||||||
// Guava: Google test library (collections test suite)
|
// Guava: Google test library (collections test suite)
|
||||||
testCompile "com.google.guava:guava-testlib:$guava_version"
|
testCompile "com.google.guava:guava-testlib:$guava_version"
|
||||||
@ -26,8 +31,6 @@ dependencies {
|
|||||||
|
|
||||||
jar {
|
jar {
|
||||||
baseName 'corda-confidential-identities'
|
baseName 'corda-confidential-identities'
|
||||||
preserveFileTimestamps = false
|
|
||||||
reproducibleFileOrder = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
publish {
|
publish {
|
||||||
|
@ -3,7 +3,7 @@ package net.corda.confidential
|
|||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import com.natpryce.hamkrest.MatchResult
|
import com.natpryce.hamkrest.MatchResult
|
||||||
import com.natpryce.hamkrest.Matcher
|
import com.natpryce.hamkrest.Matcher
|
||||||
import com.natpryce.hamkrest.assertion.assert
|
import com.natpryce.hamkrest.assertion.assertThat
|
||||||
import com.natpryce.hamkrest.equalTo
|
import com.natpryce.hamkrest.equalTo
|
||||||
import net.corda.core.crypto.DigitalSignature
|
import net.corda.core.crypto.DigitalSignature
|
||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
@ -18,7 +18,10 @@ import net.corda.testing.core.*
|
|||||||
import net.corda.testing.internal.matchers.allOf
|
import net.corda.testing.internal.matchers.allOf
|
||||||
import net.corda.testing.internal.matchers.flow.willReturn
|
import net.corda.testing.internal.matchers.flow.willReturn
|
||||||
import net.corda.testing.internal.matchers.hasOnlyEntries
|
import net.corda.testing.internal.matchers.hasOnlyEntries
|
||||||
import net.corda.testing.node.internal.*
|
import net.corda.testing.node.internal.InternalMockNetwork
|
||||||
|
import net.corda.testing.node.internal.TestStartedNode
|
||||||
|
import net.corda.testing.node.internal.enclosedCordapp
|
||||||
|
import net.corda.testing.node.internal.startFlow
|
||||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
import org.junit.AfterClass
|
import org.junit.AfterClass
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -45,7 +48,7 @@ class SwapIdentitiesFlowTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `issue key`() {
|
fun `issue key`() {
|
||||||
assert.that(
|
assertThat(
|
||||||
aliceNode.services.startFlow(SwapIdentitiesInitiator(bob)),
|
aliceNode.services.startFlow(SwapIdentitiesInitiator(bob)),
|
||||||
willReturn(
|
willReturn(
|
||||||
hasOnlyEntries(
|
hasOnlyEntries(
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# their own projects. So don't get fancy with syntax!
|
# their own projects. So don't get fancy with syntax!
|
||||||
|
|
||||||
cordaVersion=5.0-SNAPSHOT
|
cordaVersion=5.0-SNAPSHOT
|
||||||
gradlePluginsVersion=4.0.42
|
gradlePluginsVersion=5.0.1
|
||||||
kotlinVersion=1.2.71
|
kotlinVersion=1.2.71
|
||||||
java8MinUpdateVersion=171
|
java8MinUpdateVersion=171
|
||||||
# ***************************************************************#
|
# ***************************************************************#
|
||||||
|
@ -12,10 +12,13 @@ dependencies {
|
|||||||
transitive = false
|
transitive = false
|
||||||
}
|
}
|
||||||
|
|
||||||
testCompile "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
|
testImplementation "org.slf4j:slf4j-api:$slf4j_version"
|
||||||
|
testRuntimeOnly "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
|
||||||
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
||||||
testCompile "org.assertj:assertj-core:$assertj_version"
|
testCompile "org.assertj:assertj-core:$assertj_version"
|
||||||
testCompile "junit:junit:$junit_version"
|
testImplementation "junit:junit:$junit_version"
|
||||||
|
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
|
||||||
|
testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
|
||||||
}
|
}
|
||||||
|
|
||||||
// This module has no artifact and only contains tests.
|
// This module has no artifact and only contains tests.
|
||||||
|
@ -12,7 +12,11 @@ dependencies {
|
|||||||
|
|
||||||
testCompile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
|
testCompile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
|
||||||
testCompile "org.jetbrains.kotlin:kotlin-reflect"
|
testCompile "org.jetbrains.kotlin:kotlin-reflect"
|
||||||
testCompile "junit:junit:$junit_version"
|
|
||||||
|
testImplementation "junit:junit:$junit_version"
|
||||||
|
|
||||||
|
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
|
||||||
|
testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
|
||||||
}
|
}
|
||||||
|
|
||||||
jar.enabled = false
|
jar.enabled = false
|
||||||
|
@ -21,6 +21,7 @@ dependencies {
|
|||||||
// Compile against the deterministic artifacts to ensure that we use only the deterministic API subset.
|
// Compile against the deterministic artifacts to ensure that we use only the deterministic API subset.
|
||||||
compileOnly configurations.deterministicArtifacts
|
compileOnly configurations.deterministicArtifacts
|
||||||
api "junit:junit:$junit_version"
|
api "junit:junit:$junit_version"
|
||||||
|
runtimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package net.corda.deterministic.verifier
|
package net.corda.deterministic.verifier
|
||||||
|
|
||||||
import net.corda.core.serialization.ClassWhitelist
|
|
||||||
import net.corda.core.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
import net.corda.core.serialization.SerializationContext.UseCase.P2P
|
import net.corda.core.serialization.SerializationContext.UseCase.P2P
|
||||||
import net.corda.core.serialization.SerializationCustomSerializer
|
import net.corda.core.serialization.SerializationCustomSerializer
|
||||||
|
@ -11,10 +11,10 @@ evaluationDependsOn(':node:capsule')
|
|||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
integrationTestCompile.extendsFrom testCompile
|
integrationTestCompile.extendsFrom testCompile
|
||||||
integrationTestRuntime.extendsFrom testRuntime
|
integrationTestRuntimeOnly.extendsFrom testRuntimeOnly
|
||||||
|
|
||||||
smokeTestCompile.extendsFrom compile
|
smokeTestCompile.extendsFrom compile
|
||||||
smokeTestRuntime.extendsFrom runtime
|
smokeTestRuntimeOnly.extendsFrom runtimeOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@ -54,7 +54,13 @@ processSmokeTestResources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testCompile "junit:junit:$junit_version"
|
|
||||||
|
testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}"
|
||||||
|
testImplementation "junit:junit:$junit_version"
|
||||||
|
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
|
||||||
|
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_jupiter_version}"
|
||||||
|
testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
|
||||||
|
|
||||||
testCompile "commons-fileupload:commons-fileupload:$fileupload_version"
|
testCompile "commons-fileupload:commons-fileupload:$fileupload_version"
|
||||||
|
|
||||||
// Guava: Google test library (collections test suite)
|
// Guava: Google test library (collections test suite)
|
||||||
@ -87,9 +93,15 @@ dependencies {
|
|||||||
compile "com.github.ben-manes.caffeine:caffeine:$caffeine_version"
|
compile "com.github.ben-manes.caffeine:caffeine:$caffeine_version"
|
||||||
|
|
||||||
// Smoke tests do NOT have any Node code on the classpath!
|
// Smoke tests do NOT have any Node code on the classpath!
|
||||||
|
smokeTestImplementation "org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}"
|
||||||
|
smokeTestImplementation "junit:junit:$junit_version"
|
||||||
|
|
||||||
|
smokeTestRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit_vintage_version}"
|
||||||
|
smokeTestRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_jupiter_version}"
|
||||||
|
smokeTestRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
|
||||||
|
|
||||||
smokeTestCompile project(':smoke-test-utils')
|
smokeTestCompile project(':smoke-test-utils')
|
||||||
smokeTestCompile "org.assertj:assertj-core:${assertj_version}"
|
smokeTestCompile "org.assertj:assertj-core:${assertj_version}"
|
||||||
smokeTestCompile "junit:junit:$junit_version"
|
|
||||||
|
|
||||||
// RxJava: observable streams of events.
|
// RxJava: observable streams of events.
|
||||||
compile "io.reactivex:rxjava:$rxjava_version"
|
compile "io.reactivex:rxjava:$rxjava_version"
|
||||||
@ -97,7 +109,8 @@ dependencies {
|
|||||||
// Apache JEXL: An embeddable expression evaluation library.
|
// Apache JEXL: An embeddable expression evaluation library.
|
||||||
// This may be temporary until we experiment with other ways to do on-the-fly contract specialisation via an API.
|
// This may be temporary until we experiment with other ways to do on-the-fly contract specialisation via an API.
|
||||||
compile "org.apache.commons:commons-jexl3:3.0"
|
compile "org.apache.commons:commons-jexl3:3.0"
|
||||||
compile 'commons-lang:commons-lang:2.6'
|
|
||||||
|
compile "org.apache.commons:commons-lang3:3.9"
|
||||||
|
|
||||||
// Java ed25519 implementation. See https://github.com/str4d/ed25519-java/
|
// Java ed25519 implementation. See https://github.com/str4d/ed25519-java/
|
||||||
compile "net.i2p.crypto:eddsa:$eddsa_version"
|
compile "net.i2p.crypto:eddsa:$eddsa_version"
|
||||||
@ -128,7 +141,12 @@ jar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
testArtifacts.extendsFrom testRuntime
|
testArtifacts.extendsFrom testRuntimeClasspath
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(Test) {
|
||||||
|
// fork a new test process for every test class
|
||||||
|
forkEvery = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
task testJar(type: Jar) {
|
task testJar(type: Jar) {
|
||||||
@ -152,6 +170,35 @@ task smokeTest(type: Test) {
|
|||||||
classpath = sourceSets.smokeTest.runtimeClasspath
|
classpath = sourceSets.smokeTest.runtimeClasspath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// quasar exclusions upon agent code instrumentation at run-time
|
||||||
|
quasar {
|
||||||
|
excludePackages.addAll(
|
||||||
|
"antlr**",
|
||||||
|
"com.codahale**",
|
||||||
|
"com.fasterxml.**",
|
||||||
|
"com.github.benmanes.caffeine.**",
|
||||||
|
"com.google.**",
|
||||||
|
"com.lmax.**",
|
||||||
|
"com.zaxxer.**",
|
||||||
|
"net.bytebuddy**",
|
||||||
|
"io.github.classgraph**",
|
||||||
|
"io.netty*",
|
||||||
|
"liquibase**",
|
||||||
|
"net.i2p.crypto.**",
|
||||||
|
"nonapi.io.github.classgraph.**",
|
||||||
|
"org.apiguardian.**",
|
||||||
|
"org.bouncycastle**",
|
||||||
|
"org.codehaus.**",
|
||||||
|
"org.h2**",
|
||||||
|
"org.hibernate**",
|
||||||
|
"org.jboss.**",
|
||||||
|
"org.objenesis**",
|
||||||
|
"org.w3c.**",
|
||||||
|
"org.xml**",
|
||||||
|
"org.yaml**",
|
||||||
|
"rx**")
|
||||||
|
}
|
||||||
|
|
||||||
artifacts {
|
artifacts {
|
||||||
testArtifacts testJar
|
testArtifacts testJar
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package net.corda.core.contracts
|
package net.corda.core.contracts
|
||||||
|
|
||||||
|
import net.corda.core.DeleteForDJVM
|
||||||
|
import net.corda.core.KeepForDJVM
|
||||||
import net.corda.core.node.ServiceHub
|
import net.corda.core.node.ServiceHub
|
||||||
import net.corda.core.node.services.Vault
|
import net.corda.core.node.services.Vault
|
||||||
import net.corda.core.node.services.queryBy
|
import net.corda.core.node.services.queryBy
|
||||||
@ -14,6 +16,7 @@ import net.corda.core.transactions.LedgerTransaction
|
|||||||
* [StaticPointer]s are for use with any type of [ContractState].
|
* [StaticPointer]s are for use with any type of [ContractState].
|
||||||
*/
|
*/
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
|
@KeepForDJVM
|
||||||
sealed class StatePointer<T : ContractState> {
|
sealed class StatePointer<T : ContractState> {
|
||||||
/**
|
/**
|
||||||
* An identifier for the [ContractState] that this [StatePointer] points to.
|
* An identifier for the [ContractState] that this [StatePointer] points to.
|
||||||
@ -31,6 +34,7 @@ sealed class StatePointer<T : ContractState> {
|
|||||||
*
|
*
|
||||||
* @param services a [ServiceHub] implementation is required to resolve the pointer.
|
* @param services a [ServiceHub] implementation is required to resolve the pointer.
|
||||||
*/
|
*/
|
||||||
|
@DeleteForDJVM
|
||||||
abstract fun resolve(services: ServiceHub): StateAndRef<T>
|
abstract fun resolve(services: ServiceHub): StateAndRef<T>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,12 +53,14 @@ sealed class StatePointer<T : ContractState> {
|
|||||||
* - The [ContractState] may not be known by the node performing the look-up in which case the [resolve] method will
|
* - The [ContractState] may not be known by the node performing the look-up in which case the [resolve] method will
|
||||||
* throw a [TransactionResolutionException]
|
* throw a [TransactionResolutionException]
|
||||||
*/
|
*/
|
||||||
|
@KeepForDJVM
|
||||||
class StaticPointer<T : ContractState>(override val pointer: StateRef, override val type: Class<T>) : StatePointer<T>() {
|
class StaticPointer<T : ContractState>(override val pointer: StateRef, override val type: Class<T>) : StatePointer<T>() {
|
||||||
/**
|
/**
|
||||||
* Resolves a [StaticPointer] to a [StateAndRef] via a [StateRef] look-up.
|
* Resolves a [StaticPointer] to a [StateAndRef] via a [StateRef] look-up.
|
||||||
*/
|
*/
|
||||||
@Throws(TransactionResolutionException::class)
|
@Throws(TransactionResolutionException::class)
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
@DeleteForDJVM
|
||||||
override fun resolve(services: ServiceHub): StateAndRef<T> {
|
override fun resolve(services: ServiceHub): StateAndRef<T> {
|
||||||
val transactionState = services.loadState(pointer) as TransactionState<T>
|
val transactionState = services.loadState(pointer) as TransactionState<T>
|
||||||
val castState: T = type.cast(transactionState.data)
|
val castState: T = type.cast(transactionState.data)
|
||||||
@ -92,6 +98,7 @@ class StaticPointer<T : ContractState>(override val pointer: StateRef, override
|
|||||||
* then the transaction with such a reference state cannot be committed to the ledger until the most up-to-date version
|
* then the transaction with such a reference state cannot be committed to the ledger until the most up-to-date version
|
||||||
* of the [LinearState] is available. See reference states documentation on docs.corda.net for more info.
|
* of the [LinearState] is available. See reference states documentation on docs.corda.net for more info.
|
||||||
*/
|
*/
|
||||||
|
@KeepForDJVM
|
||||||
class LinearPointer<T : LinearState>(override val pointer: UniqueIdentifier, override val type: Class<T>) : StatePointer<T>() {
|
class LinearPointer<T : LinearState>(override val pointer: UniqueIdentifier, override val type: Class<T>) : StatePointer<T>() {
|
||||||
/**
|
/**
|
||||||
* Resolves a [LinearPointer] using the [UniqueIdentifier] contained in the [pointer] property. Returns a
|
* Resolves a [LinearPointer] using the [UniqueIdentifier] contained in the [pointer] property. Returns a
|
||||||
@ -100,6 +107,7 @@ class LinearPointer<T : LinearState>(override val pointer: UniqueIdentifier, ove
|
|||||||
* @param services a [ServiceHub] implementation is required to perform a vault query.
|
* @param services a [ServiceHub] implementation is required to perform a vault query.
|
||||||
*/
|
*/
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
@DeleteForDJVM
|
||||||
override fun resolve(services: ServiceHub): StateAndRef<T> {
|
override fun resolve(services: ServiceHub): StateAndRef<T> {
|
||||||
// Return the latest version of the linear state.
|
// Return the latest version of the linear state.
|
||||||
// This query will only ever return one or zero states.
|
// This query will only ever return one or zero states.
|
||||||
|
@ -266,7 +266,6 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
|
|||||||
/**
|
/**
|
||||||
* Thrown when multiple attachments provide the same file when building the AttachmentsClassloader for a transaction.
|
* Thrown when multiple attachments provide the same file when building the AttachmentsClassloader for a transaction.
|
||||||
*/
|
*/
|
||||||
@CordaSerializable
|
|
||||||
@KeepForDJVM
|
@KeepForDJVM
|
||||||
class OverlappingAttachmentsException(txId: SecureHash, val path: String) : TransactionVerificationException(txId, "Multiple attachments define a file at $path.", null)
|
class OverlappingAttachmentsException(txId: SecureHash, val path: String) : TransactionVerificationException(txId, "Multiple attachments define a file at $path.", null)
|
||||||
|
|
||||||
@ -275,20 +274,17 @@ abstract class TransactionVerificationException(val txId: SecureHash, message: S
|
|||||||
* the [txId] will always be [SecureHash.zeroHash] because package ownership is an error with a particular attachment,
|
* the [txId] will always be [SecureHash.zeroHash] because package ownership is an error with a particular attachment,
|
||||||
* and because attachment classloaders are reused this is independent of any particular transaction.
|
* and because attachment classloaders are reused this is independent of any particular transaction.
|
||||||
*/
|
*/
|
||||||
@CordaSerializable
|
|
||||||
class PackageOwnershipException(txId: SecureHash, @Suppress("unused") val attachmentHash: AttachmentId, @Suppress("unused") val invalidClassName: String, val packageName: String) : TransactionVerificationException(txId,
|
class PackageOwnershipException(txId: SecureHash, @Suppress("unused") val attachmentHash: AttachmentId, @Suppress("unused") val invalidClassName: String, val packageName: String) : TransactionVerificationException(txId,
|
||||||
"""The attachment JAR: $attachmentHash containing the class: $invalidClassName is not signed by the owner of package $packageName specified in the network parameters.
|
"""The attachment JAR: $attachmentHash containing the class: $invalidClassName is not signed by the owner of package $packageName specified in the network parameters.
|
||||||
Please check the source of this attachment and if it is malicious contact your zone operator to report this incident.
|
Please check the source of this attachment and if it is malicious contact your zone operator to report this incident.
|
||||||
For details see: https://docs.corda.net/network-map.html#network-parameters""".trimIndent(), null)
|
For details see: https://docs.corda.net/network-map.html#network-parameters""".trimIndent(), null)
|
||||||
|
|
||||||
@CordaSerializable
|
|
||||||
class InvalidAttachmentException(txId: SecureHash, @Suppress("unused") val attachmentHash: AttachmentId) : TransactionVerificationException(txId,
|
class InvalidAttachmentException(txId: SecureHash, @Suppress("unused") val attachmentHash: AttachmentId) : TransactionVerificationException(txId,
|
||||||
"The attachment $attachmentHash is not a valid ZIP or JAR file.".trimIndent(), null)
|
"The attachment $attachmentHash is not a valid ZIP or JAR file.".trimIndent(), null)
|
||||||
|
|
||||||
// TODO: Make this descend from TransactionVerificationException so that untrusted attachments cause flows to be hospitalized.
|
// TODO: Make this descend from TransactionVerificationException so that untrusted attachments cause flows to be hospitalized.
|
||||||
/** Thrown during classloading upon encountering an untrusted attachment (eg. not in the [TRUSTED_UPLOADERS] list) */
|
/** Thrown during classloading upon encountering an untrusted attachment (eg. not in the [TRUSTED_UPLOADERS] list) */
|
||||||
@KeepForDJVM
|
@KeepForDJVM
|
||||||
@CordaSerializable
|
|
||||||
class UntrustedAttachmentsException(val txId: SecureHash, val ids: List<SecureHash>) :
|
class UntrustedAttachmentsException(val txId: SecureHash, val ids: List<SecureHash>) :
|
||||||
CordaException("Attempting to load untrusted transaction attachments: $ids. " +
|
CordaException("Attempting to load untrusted transaction attachments: $ids. " +
|
||||||
"At this time these are not loadable because the DJVM sandbox has not yet been integrated. " +
|
"At this time these are not loadable because the DJVM sandbox has not yet been integrated. " +
|
||||||
|
@ -4,7 +4,7 @@ package net.corda.core.crypto.internal
|
|||||||
|
|
||||||
import net.corda.core.DeleteForDJVM
|
import net.corda.core.DeleteForDJVM
|
||||||
import net.corda.core.crypto.newSecureRandom
|
import net.corda.core.crypto.newSecureRandom
|
||||||
import org.apache.commons.lang.SystemUtils
|
import org.apache.commons.lang3.SystemUtils
|
||||||
import java.security.Provider
|
import java.security.Provider
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
import java.security.SecureRandomSpi
|
import java.security.SecureRandomSpi
|
||||||
|
@ -83,12 +83,12 @@ data class CordaX500Name(val commonName: String?,
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun build(principal: X500Principal): CordaX500Name {
|
fun build(principal: X500Principal): CordaX500Name {
|
||||||
val attrsMap = principal.toAttributesMap(supportedAttributes)
|
val attrsMap = principal.toAttributesMap(supportedAttributes)
|
||||||
val CN = attrsMap[BCStyle.CN]?.toString()
|
val CN = attrsMap[BCStyle.CN]
|
||||||
val OU = attrsMap[BCStyle.OU]?.toString()
|
val OU = attrsMap[BCStyle.OU]
|
||||||
val O = requireNotNull(attrsMap[BCStyle.O]?.toString()) { "Corda X.500 names must include an O attribute" }
|
val O = requireNotNull(attrsMap[BCStyle.O]) { "Corda X.500 names must include an O attribute" }
|
||||||
val L = requireNotNull(attrsMap[BCStyle.L]?.toString()) { "Corda X.500 names must include an L attribute" }
|
val L = requireNotNull(attrsMap[BCStyle.L]) { "Corda X.500 names must include an L attribute" }
|
||||||
val ST = attrsMap[BCStyle.ST]?.toString()
|
val ST = attrsMap[BCStyle.ST]
|
||||||
val C = requireNotNull(attrsMap[BCStyle.C]?.toString()) { "Corda X.500 names must include an C attribute" }
|
val C = requireNotNull(attrsMap[BCStyle.C]) { "Corda X.500 names must include an C attribute" }
|
||||||
return CordaX500Name(CN, OU, O, L, ST, C)
|
return CordaX500Name(CN, OU, O, L, ST, C)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package net.corda.core.internal
|
|||||||
|
|
||||||
import net.corda.core.contracts.ContractState
|
import net.corda.core.contracts.ContractState
|
||||||
import net.corda.core.contracts.StatePointer
|
import net.corda.core.contracts.StatePointer
|
||||||
|
import org.apache.commons.lang3.reflect.FieldUtils
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -25,20 +26,9 @@ class StatePointerSearch(val state: ContractState) {
|
|||||||
// Queue of fields to search.
|
// Queue of fields to search.
|
||||||
private val fieldQueue = ArrayDeque<FieldWithObject>().apply { addAllFields(state) }
|
private val fieldQueue = ArrayDeque<FieldWithObject>().apply { addAllFields(state) }
|
||||||
|
|
||||||
// Get fields of class and all super-classes.
|
|
||||||
private fun getAllFields(clazz: Class<*>): List<Field> {
|
|
||||||
val fields = mutableListOf<Field>()
|
|
||||||
var currentClazz = clazz
|
|
||||||
while (currentClazz.superclass != null) {
|
|
||||||
fields.addAll(currentClazz.declaredFields)
|
|
||||||
currentClazz = currentClazz.superclass
|
|
||||||
}
|
|
||||||
return fields
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper for adding all fields to the queue.
|
// Helper for adding all fields to the queue.
|
||||||
private fun ArrayDeque<FieldWithObject>.addAllFields(obj: Any) {
|
private fun ArrayDeque<FieldWithObject>.addAllFields(obj: Any) {
|
||||||
val fields = getAllFields(obj::class.java)
|
val fields = FieldUtils.getAllFieldsList(obj::class.java)
|
||||||
|
|
||||||
val fieldsWithObjects = fields.mapNotNull { field ->
|
val fieldsWithObjects = fields.mapNotNull { field ->
|
||||||
// Ignore classes which have not been loaded.
|
// Ignore classes which have not been loaded.
|
||||||
|
@ -41,14 +41,14 @@ fun X500Principal.toX500Name(): X500Name = X500Name.getInstance(this.encoded)
|
|||||||
* @throws IllegalArgumentException if this principal consists of duplicated attributes or the attribute is not supported.
|
* @throws IllegalArgumentException if this principal consists of duplicated attributes or the attribute is not supported.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
fun X500Principal.toAttributesMap(supportedAttributes: Set<ASN1ObjectIdentifier> = emptySet()): Map<ASN1ObjectIdentifier, ASN1Encodable> {
|
fun X500Principal.toAttributesMap(supportedAttributes: Set<ASN1ObjectIdentifier> = emptySet()): Map<ASN1ObjectIdentifier, String> {
|
||||||
val x500Name = this.toX500Name()
|
val x500Name = this.toX500Name()
|
||||||
val attrsMap: Map<ASN1ObjectIdentifier, ASN1Encodable> = x500Name.rdNs
|
val attrsMap: Map<ASN1ObjectIdentifier, String> = x500Name.rdNs
|
||||||
.flatMap { it.typesAndValues.asList() }
|
.flatMap { it.typesAndValues.asList() }
|
||||||
.groupBy(AttributeTypeAndValue::getType, AttributeTypeAndValue::getValue)
|
.groupBy(AttributeTypeAndValue::getType, AttributeTypeAndValue::getValue)
|
||||||
.mapValues {
|
.mapValues {
|
||||||
require(it.value.size == 1) { "Duplicate attribute ${it.key}" }
|
require(it.value.size == 1) { "Duplicate attribute ${it.key}" }
|
||||||
it.value[0]
|
it.value[0].toString()
|
||||||
}
|
}
|
||||||
if (supportedAttributes.isNotEmpty()) {
|
if (supportedAttributes.isNotEmpty()) {
|
||||||
(attrsMap.keys - supportedAttributes).let { unsupported ->
|
(attrsMap.keys - supportedAttributes).let { unsupported ->
|
||||||
|
@ -19,6 +19,7 @@ import java.io.IOException
|
|||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.net.*
|
import java.net.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.jar.JarInputStream
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A custom ClassLoader that knows how to load classes from a set of attachments. The attachments themselves only
|
* A custom ClassLoader that knows how to load classes from a set of attachments. The attachments themselves only
|
||||||
@ -139,7 +140,7 @@ class AttachmentsClassLoader(attachments: List<Attachment>,
|
|||||||
attachment.openAsJAR().use { jar ->
|
attachment.openAsJAR().use { jar ->
|
||||||
while (true) {
|
while (true) {
|
||||||
val entry = jar.nextJarEntry ?: return false
|
val entry = jar.nextJarEntry ?: return false
|
||||||
if(entry.name.endsWith(".class", ignoreCase = true)) return true
|
if (entry.name.endsWith(".class", ignoreCase = true)) return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -190,7 +191,7 @@ class AttachmentsClassLoader(attachments: List<Attachment>,
|
|||||||
// attacks on externally connected systems that only consider type names, we allow people to formally
|
// attacks on externally connected systems that only consider type names, we allow people to formally
|
||||||
// claim their parts of the Java package namespace via registration with the zone operator.
|
// claim their parts of the Java package namespace via registration with the zone operator.
|
||||||
|
|
||||||
val classLoaderEntries = mutableMapOf<String, Attachment>()
|
val classLoaderEntries = mutableMapOf<String, SecureHash.SHA256>()
|
||||||
for (attachment in attachments) {
|
for (attachment in attachments) {
|
||||||
// We may have been given an attachment loaded from the database in which case, important info like
|
// We may have been given an attachment loaded from the database in which case, important info like
|
||||||
// signers is already calculated.
|
// signers is already calculated.
|
||||||
@ -251,21 +252,26 @@ class AttachmentsClassLoader(attachments: List<Attachment>,
|
|||||||
// Some files don't need overlap checking because they don't affect the way the code runs.
|
// Some files don't need overlap checking because they don't affect the way the code runs.
|
||||||
if (!shouldCheckForNoOverlap(path, targetPlatformVersion)) continue
|
if (!shouldCheckForNoOverlap(path, targetPlatformVersion)) continue
|
||||||
|
|
||||||
// If 2 entries have the same content hash, it means the same file is present in both attachments, so that is ok.
|
// This calculates the hash of the current entry because the JarInputStream returns only the current entry.
|
||||||
if (path in classLoaderEntries.keys) {
|
fun entryHash() = ByteArrayOutputStream().use {
|
||||||
val contentHash = readAttachment(attachment, path).sha256()
|
jar.copyTo(it)
|
||||||
val originalAttachment = classLoaderEntries[path]!!
|
it.toByteArray()
|
||||||
val originalContentHash = readAttachment(originalAttachment, path).sha256()
|
}.sha256()
|
||||||
if (contentHash == originalContentHash) {
|
|
||||||
log.debug { "Duplicate entry $path has same content hash $contentHash" }
|
// If 2 entries are identical, it means the same file is present in both attachments, so that is ok.
|
||||||
continue
|
val currentHash = entryHash()
|
||||||
} else {
|
val previousFileHash = classLoaderEntries[path]
|
||||||
|
when {
|
||||||
|
previousFileHash == null -> {
|
||||||
|
log.debug { "Adding new entry for $path" }
|
||||||
|
classLoaderEntries[path] = currentHash
|
||||||
|
}
|
||||||
|
currentHash == previousFileHash -> log.debug { "Duplicate entry $path has same content hash $currentHash" }
|
||||||
|
else -> {
|
||||||
log.debug { "Content hash differs for $path" }
|
log.debug { "Content hash differs for $path" }
|
||||||
throw OverlappingAttachmentsException(sampleTxId, path)
|
throw OverlappingAttachmentsException(sampleTxId, path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.debug { "Adding new entry for $path" }
|
|
||||||
classLoaderEntries[path] = attachment
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.debug { "${classLoaderEntries.size} classloaded entries for $attachment" }
|
log.debug { "${classLoaderEntries.size} classloaded entries for $attachment" }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package net.corda.core.crypto
|
package net.corda.core.crypto
|
||||||
|
|
||||||
import org.apache.commons.lang.ArrayUtils.EMPTY_BYTE_ARRAY
|
import org.apache.commons.lang3.ArrayUtils.EMPTY_BYTE_ARRAY
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -15,7 +15,7 @@ import net.i2p.crypto.eddsa.math.GroupElement
|
|||||||
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec
|
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec
|
||||||
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable
|
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable
|
||||||
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec
|
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec
|
||||||
import org.apache.commons.lang.ArrayUtils.EMPTY_BYTE_ARRAY
|
import org.apache.commons.lang3.ArrayUtils.EMPTY_BYTE_ARRAY
|
||||||
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo
|
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo
|
||||||
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
|
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
|
||||||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
|
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
|
||||||
|
@ -2,7 +2,7 @@ package net.corda.core.flows
|
|||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import com.natpryce.hamkrest.*
|
import com.natpryce.hamkrest.*
|
||||||
import com.natpryce.hamkrest.assertion.assert
|
import com.natpryce.hamkrest.assertion.assertThat
|
||||||
import net.corda.core.contracts.Attachment
|
import net.corda.core.contracts.Attachment
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.flows.mixins.WithMockNet
|
import net.corda.core.flows.mixins.WithMockNet
|
||||||
@ -48,18 +48,18 @@ class AttachmentTests : WithMockNet {
|
|||||||
val id = aliceNode.importAttachment(fakeAttachment("file1.txt", "Some useful content"))
|
val id = aliceNode.importAttachment(fakeAttachment("file1.txt", "Some useful content"))
|
||||||
|
|
||||||
// Get node one to run a flow to fetch it and insert it.
|
// Get node one to run a flow to fetch it and insert it.
|
||||||
assert.that(
|
assertThat(
|
||||||
bobNode.startAttachmentFlow(id, alice),
|
bobNode.startAttachmentFlow(id, alice),
|
||||||
willReturn(noAttachments()))
|
willReturn(noAttachments()))
|
||||||
|
|
||||||
// Verify it was inserted into node one's store.
|
// Verify it was inserted into node one's store.
|
||||||
val attachment = bobNode.getAttachmentWithId(id)
|
val attachment = bobNode.getAttachmentWithId(id)
|
||||||
assert.that(attachment, hashesTo(id))
|
assertThat(attachment, hashesTo(id))
|
||||||
|
|
||||||
// Shut down node zero and ensure node one can still resolve the attachment.
|
// Shut down node zero and ensure node one can still resolve the attachment.
|
||||||
aliceNode.dispose()
|
aliceNode.dispose()
|
||||||
|
|
||||||
assert.that(
|
assertThat(
|
||||||
bobNode.startAttachmentFlow(id, alice),
|
bobNode.startAttachmentFlow(id, alice),
|
||||||
willReturn(soleAttachment(attachment)))
|
willReturn(soleAttachment(attachment)))
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ class AttachmentTests : WithMockNet {
|
|||||||
val hash: SecureHash = SecureHash.randomSHA256()
|
val hash: SecureHash = SecureHash.randomSHA256()
|
||||||
|
|
||||||
// Get node one to fetch a non-existent attachment.
|
// Get node one to fetch a non-existent attachment.
|
||||||
assert.that(
|
assertThat(
|
||||||
bobNode.startAttachmentFlow(hash, alice),
|
bobNode.startAttachmentFlow(hash, alice),
|
||||||
willThrow(withRequestedHash(hash)))
|
willThrow(withRequestedHash(hash)))
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ class AttachmentTests : WithMockNet {
|
|||||||
badAliceNode.updateAttachment(corruptAttachment)
|
badAliceNode.updateAttachment(corruptAttachment)
|
||||||
|
|
||||||
// Get n1 to fetch the attachment. Should receive corrupted bytes.
|
// Get n1 to fetch the attachment. Should receive corrupted bytes.
|
||||||
assert.that(
|
assertThat(
|
||||||
bobNode.startAttachmentFlow(id, badAlice),
|
bobNode.startAttachmentFlow(id, badAlice),
|
||||||
willThrow<FetchDataFlow.DownloadedVsRequestedDataMismatch>()
|
willThrow<FetchDataFlow.DownloadedVsRequestedDataMismatch>()
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.corda.core.flows
|
package net.corda.core.flows
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import com.natpryce.hamkrest.assertion.assert
|
import com.natpryce.hamkrest.assertion.assertThat
|
||||||
import net.corda.core.contracts.Command
|
import net.corda.core.contracts.Command
|
||||||
import net.corda.core.contracts.StateAndContract
|
import net.corda.core.contracts.StateAndContract
|
||||||
import net.corda.core.contracts.requireThat
|
import net.corda.core.contracts.requireThat
|
||||||
@ -55,7 +55,7 @@ class CollectSignaturesFlowTests : WithContracts {
|
|||||||
val bConfidentialIdentity = bobNode.createConfidentialIdentity(bob)
|
val bConfidentialIdentity = bobNode.createConfidentialIdentity(bob)
|
||||||
aliceNode.verifyAndRegister(bConfidentialIdentity)
|
aliceNode.verifyAndRegister(bConfidentialIdentity)
|
||||||
|
|
||||||
assert.that(
|
assertThat(
|
||||||
aliceNode.startTestFlow(alice, bConfidentialIdentity.party, charlie),
|
aliceNode.startTestFlow(alice, bConfidentialIdentity.party, charlie),
|
||||||
willReturn(requiredSignatures(3))
|
willReturn(requiredSignatures(3))
|
||||||
)
|
)
|
||||||
@ -113,7 +113,7 @@ class CollectSignaturesFlowTests : WithContracts {
|
|||||||
fun `no need to collect any signatures`() {
|
fun `no need to collect any signatures`() {
|
||||||
val ptx = aliceNode.signDummyContract(alice.ref(1))
|
val ptx = aliceNode.signDummyContract(alice.ref(1))
|
||||||
|
|
||||||
assert.that(
|
assertThat(
|
||||||
aliceNode.collectSignatures(ptx),
|
aliceNode.collectSignatures(ptx),
|
||||||
willReturn(requiredSignatures(1))
|
willReturn(requiredSignatures(1))
|
||||||
)
|
)
|
||||||
@ -123,7 +123,7 @@ class CollectSignaturesFlowTests : WithContracts {
|
|||||||
fun `fails when not signed by initiator`() {
|
fun `fails when not signed by initiator`() {
|
||||||
val ptx = miniCorpServices.signDummyContract(alice.ref(1))
|
val ptx = miniCorpServices.signDummyContract(alice.ref(1))
|
||||||
|
|
||||||
assert.that(
|
assertThat(
|
||||||
aliceNode.collectSignatures(ptx),
|
aliceNode.collectSignatures(ptx),
|
||||||
willThrow(errorMessage("The Initiator of CollectSignaturesFlow must have signed the transaction.")))
|
willThrow(errorMessage("The Initiator of CollectSignaturesFlow must have signed the transaction.")))
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ class CollectSignaturesFlowTests : WithContracts {
|
|||||||
bob.ref(3))
|
bob.ref(3))
|
||||||
val signedByBoth = bobNode.addSignatureTo(signedByA)
|
val signedByBoth = bobNode.addSignatureTo(signedByA)
|
||||||
|
|
||||||
assert.that(
|
assertThat(
|
||||||
aliceNode.collectSignatures(signedByBoth),
|
aliceNode.collectSignatures(signedByBoth),
|
||||||
willReturn(requiredSignatures(2))
|
willReturn(requiredSignatures(2))
|
||||||
)
|
)
|
||||||
|
@ -2,7 +2,7 @@ package net.corda.core.flows
|
|||||||
|
|
||||||
import com.natpryce.hamkrest.and
|
import com.natpryce.hamkrest.and
|
||||||
import com.natpryce.hamkrest.anything
|
import com.natpryce.hamkrest.anything
|
||||||
import com.natpryce.hamkrest.assertion.assert
|
import com.natpryce.hamkrest.assertion.assertThat
|
||||||
import com.natpryce.hamkrest.has
|
import com.natpryce.hamkrest.has
|
||||||
import com.natpryce.hamkrest.isA
|
import com.natpryce.hamkrest.isA
|
||||||
import net.corda.core.CordaRuntimeException
|
import net.corda.core.CordaRuntimeException
|
||||||
@ -52,30 +52,30 @@ class ContractUpgradeFlowRPCTest : WithContracts, WithFinality {
|
|||||||
// Create, sign and finalise dummy contract.
|
// Create, sign and finalise dummy contract.
|
||||||
val signedByA = aliceNode.signDummyContract(alice.ref(1), 0, bob.ref(1))
|
val signedByA = aliceNode.signDummyContract(alice.ref(1), 0, bob.ref(1))
|
||||||
val stx = bobNode.addSignatureTo(signedByA)
|
val stx = bobNode.addSignatureTo(signedByA)
|
||||||
assert.that(rpcA.finalise(stx, bob), willReturn())
|
assertThat(rpcA.finalise(stx, bob), willReturn())
|
||||||
|
|
||||||
val atx = aliceNode.getValidatedTransaction(stx)
|
val atx = aliceNode.getValidatedTransaction(stx)
|
||||||
val btx = bobNode.getValidatedTransaction(stx)
|
val btx = bobNode.getValidatedTransaction(stx)
|
||||||
|
|
||||||
// Cannot upgrade contract without prior authorisation from counterparty
|
// Cannot upgrade contract without prior authorisation from counterparty
|
||||||
assert.that(
|
assertThat(
|
||||||
rpcA.initiateDummyContractUpgrade(atx),
|
rpcA.initiateDummyContractUpgrade(atx),
|
||||||
willThrow<CordaRuntimeException>())
|
willThrow<CordaRuntimeException>())
|
||||||
|
|
||||||
// Party B authorises the contract state upgrade, and immediately deauthorises the same.
|
// Party B authorises the contract state upgrade, and immediately deauthorises the same.
|
||||||
assert.that(rpcB.authoriseDummyContractUpgrade(btx), willReturn())
|
assertThat(rpcB.authoriseDummyContractUpgrade(btx), willReturn())
|
||||||
assert.that(rpcB.deauthoriseContractUpgrade(btx), willReturn())
|
assertThat(rpcB.deauthoriseContractUpgrade(btx), willReturn())
|
||||||
|
|
||||||
// Cannot upgrade contract if counterparty has deauthorised a previously-given authority
|
// Cannot upgrade contract if counterparty has deauthorised a previously-given authority
|
||||||
assert.that(
|
assertThat(
|
||||||
rpcA.initiateDummyContractUpgrade(atx),
|
rpcA.initiateDummyContractUpgrade(atx),
|
||||||
willThrow<CordaRuntimeException>())
|
willThrow<CordaRuntimeException>())
|
||||||
|
|
||||||
// Party B authorise the contract state upgrade.
|
// Party B authorise the contract state upgrade.
|
||||||
assert.that(rpcB.authoriseDummyContractUpgrade(btx), willReturn())
|
assertThat(rpcB.authoriseDummyContractUpgrade(btx), willReturn())
|
||||||
|
|
||||||
// Party A initiates contract upgrade flow, expected to succeed this time.
|
// Party A initiates contract upgrade flow, expected to succeed this time.
|
||||||
assert.that(
|
assertThat(
|
||||||
rpcA.initiateDummyContractUpgrade(atx),
|
rpcA.initiateDummyContractUpgrade(atx),
|
||||||
willReturn(
|
willReturn(
|
||||||
aliceNode.hasDummyContractUpgradeTransaction()
|
aliceNode.hasDummyContractUpgradeTransaction()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.corda.core.flows
|
package net.corda.core.flows
|
||||||
|
|
||||||
import com.natpryce.hamkrest.*
|
import com.natpryce.hamkrest.*
|
||||||
import com.natpryce.hamkrest.assertion.assert
|
import com.natpryce.hamkrest.assertion.assertThat
|
||||||
import net.corda.core.contracts.*
|
import net.corda.core.contracts.*
|
||||||
import net.corda.core.flows.mixins.WithContracts
|
import net.corda.core.flows.mixins.WithContracts
|
||||||
import net.corda.core.flows.mixins.WithFinality
|
import net.corda.core.flows.mixins.WithFinality
|
||||||
@ -59,24 +59,24 @@ class ContractUpgradeFlowTest : WithContracts, WithFinality {
|
|||||||
val bobTx = bobNode.getValidatedTransaction(stx)
|
val bobTx = bobNode.getValidatedTransaction(stx)
|
||||||
|
|
||||||
// The request is expected to be rejected because party B hasn't authorised the upgrade yet.
|
// The request is expected to be rejected because party B hasn't authorised the upgrade yet.
|
||||||
assert.that(
|
assertThat(
|
||||||
aliceNode.initiateContractUpgrade(aliceTx, DummyContractV2::class),
|
aliceNode.initiateContractUpgrade(aliceTx, DummyContractV2::class),
|
||||||
willThrow<UnexpectedFlowEndException>())
|
willThrow<UnexpectedFlowEndException>())
|
||||||
|
|
||||||
// Party B authorises the contract state upgrade, and immediately de-authorises the same.
|
// Party B authorises the contract state upgrade, and immediately de-authorises the same.
|
||||||
assert.that(bobNode.authoriseContractUpgrade(bobTx, DummyContractV2::class), willReturn())
|
assertThat(bobNode.authoriseContractUpgrade(bobTx, DummyContractV2::class), willReturn())
|
||||||
assert.that(bobNode.deauthoriseContractUpgrade(bobTx), willReturn())
|
assertThat(bobNode.deauthoriseContractUpgrade(bobTx), willReturn())
|
||||||
|
|
||||||
// The request is expected to be rejected because party B has subsequently de-authorised a previously authorised upgrade.
|
// The request is expected to be rejected because party B has subsequently de-authorised a previously authorised upgrade.
|
||||||
assert.that(
|
assertThat(
|
||||||
aliceNode.initiateContractUpgrade(aliceTx, DummyContractV2::class),
|
aliceNode.initiateContractUpgrade(aliceTx, DummyContractV2::class),
|
||||||
willThrow<UnexpectedFlowEndException>())
|
willThrow<UnexpectedFlowEndException>())
|
||||||
|
|
||||||
// Party B authorises the contract state upgrade.
|
// Party B authorises the contract state upgrade.
|
||||||
assert.that(bobNode.authoriseContractUpgrade(bobTx, DummyContractV2::class), willReturn())
|
assertThat(bobNode.authoriseContractUpgrade(bobTx, DummyContractV2::class), willReturn())
|
||||||
|
|
||||||
// Party A initiates contract upgrade flow, expected to succeed this time.
|
// Party A initiates contract upgrade flow, expected to succeed this time.
|
||||||
assert.that(
|
assertThat(
|
||||||
aliceNode.initiateContractUpgrade(aliceTx, DummyContractV2::class),
|
aliceNode.initiateContractUpgrade(aliceTx, DummyContractV2::class),
|
||||||
willReturn(
|
willReturn(
|
||||||
aliceNode.hasContractUpgradeTransaction<DummyContract.State, DummyContractV2.State>()
|
aliceNode.hasContractUpgradeTransaction<DummyContract.State, DummyContractV2.State>()
|
||||||
@ -86,10 +86,10 @@ class ContractUpgradeFlowTest : WithContracts, WithFinality {
|
|||||||
|
|
||||||
// We now test that the upgraded state can be upgraded further, to V3.
|
// We now test that the upgraded state can be upgraded further, to V3.
|
||||||
// Party B authorises the contract state upgrade.
|
// Party B authorises the contract state upgrade.
|
||||||
assert.that(bobNode.authoriseContractUpgrade(upgradedState, DummyContractV3::class), willReturn())
|
assertThat(bobNode.authoriseContractUpgrade(upgradedState, DummyContractV3::class), willReturn())
|
||||||
|
|
||||||
// Party A initiates contract upgrade flow which is expected to succeed.
|
// Party A initiates contract upgrade flow which is expected to succeed.
|
||||||
assert.that(
|
assertThat(
|
||||||
aliceNode.initiateContractUpgrade(upgradedState, DummyContractV3::class),
|
aliceNode.initiateContractUpgrade(upgradedState, DummyContractV3::class),
|
||||||
willReturn(
|
willReturn(
|
||||||
aliceNode.hasContractUpgradeTransaction<DummyContractV2.State, DummyContractV3.State>()
|
aliceNode.hasContractUpgradeTransaction<DummyContractV2.State, DummyContractV3.State>()
|
||||||
@ -125,14 +125,14 @@ class ContractUpgradeFlowTest : WithContracts, WithFinality {
|
|||||||
val stateAndRef = cashFlowResult.stx.tx.outRef<Cash.State>(0)
|
val stateAndRef = cashFlowResult.stx.tx.outRef<Cash.State>(0)
|
||||||
|
|
||||||
// The un-upgraded state is Cash.State
|
// The un-upgraded state is Cash.State
|
||||||
assert.that(aliceNode.getBaseStateFromVault(), hasContractState(isA<Cash.State>(anything)))
|
assertThat(aliceNode.getBaseStateFromVault(), hasContractState(isA<Cash.State>(anything)))
|
||||||
|
|
||||||
// Starts contract upgrade flow.
|
// Starts contract upgrade flow.
|
||||||
assert.that(aliceNode.initiateContractUpgrade(stateAndRef, CashV2::class), willReturn())
|
assertThat(aliceNode.initiateContractUpgrade(stateAndRef, CashV2::class), willReturn())
|
||||||
|
|
||||||
// Get contract state from the vault.
|
// Get contract state from the vault.
|
||||||
val upgradedState = aliceNode.getCashStateFromVault()
|
val upgradedState = aliceNode.getCashStateFromVault()
|
||||||
assert.that(upgradedState,
|
assertThat(upgradedState,
|
||||||
hasIssuedAmount(Amount(1000000, USD) `issued by` (alice.ref(1)))
|
hasIssuedAmount(Amount(1000000, USD) `issued by` (alice.ref(1)))
|
||||||
and belongsTo(anonymisedRecipient))
|
and belongsTo(anonymisedRecipient))
|
||||||
|
|
||||||
@ -146,8 +146,8 @@ class ContractUpgradeFlowTest : WithContracts, WithFinality {
|
|||||||
addCommand(CashV2.Move(), alice.owningKey)
|
addCommand(CashV2.Move(), alice.owningKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.that(aliceNode.finalise(spendUpgradedTx), willReturn())
|
assertThat(aliceNode.finalise(spendUpgradedTx), willReturn())
|
||||||
assert.that(aliceNode.getCashStateFromVault(), hasContractState(equalTo(movedState)))
|
assertThat(aliceNode.getCashStateFromVault(), hasContractState(equalTo(movedState)))
|
||||||
}
|
}
|
||||||
|
|
||||||
class CashV2 : UpgradedContractWithLegacyConstraint<Cash.State, CashV2.State> {
|
class CashV2 : UpgradedContractWithLegacyConstraint<Cash.State, CashV2.State> {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.corda.core.flows
|
package net.corda.core.flows
|
||||||
|
|
||||||
import com.natpryce.hamkrest.and
|
import com.natpryce.hamkrest.and
|
||||||
import com.natpryce.hamkrest.assertion.assert
|
import com.natpryce.hamkrest.assertion.assertThat
|
||||||
import net.corda.core.flows.mixins.WithFinality
|
import net.corda.core.flows.mixins.WithFinality
|
||||||
import net.corda.core.flows.mixins.WithFinality.FinalityInvoker
|
import net.corda.core.flows.mixins.WithFinality.FinalityInvoker
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
@ -17,7 +17,6 @@ import net.corda.testing.internal.matchers.flow.willReturn
|
|||||||
import net.corda.testing.internal.matchers.flow.willThrow
|
import net.corda.testing.internal.matchers.flow.willThrow
|
||||||
import net.corda.testing.node.internal.*
|
import net.corda.testing.node.internal.*
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@ -40,7 +39,7 @@ class FinalityFlowTests : WithFinality {
|
|||||||
val bob = createBob()
|
val bob = createBob()
|
||||||
val stx = aliceNode.issuesCashTo(bob)
|
val stx = aliceNode.issuesCashTo(bob)
|
||||||
|
|
||||||
assert.that(
|
assertThat(
|
||||||
aliceNode.finalise(stx, bob.info.singleIdentity()),
|
aliceNode.finalise(stx, bob.info.singleIdentity()),
|
||||||
willReturn(
|
willReturn(
|
||||||
requiredSignatures(1)
|
requiredSignatures(1)
|
||||||
@ -52,7 +51,7 @@ class FinalityFlowTests : WithFinality {
|
|||||||
// Charlie isn't part of this network, so node A won't recognise them
|
// Charlie isn't part of this network, so node A won't recognise them
|
||||||
val stx = aliceNode.issuesCashTo(CHARLIE)
|
val stx = aliceNode.issuesCashTo(CHARLIE)
|
||||||
|
|
||||||
assert.that(
|
assertThat(
|
||||||
aliceNode.finalise(stx),
|
aliceNode.finalise(stx),
|
||||||
willThrow<IllegalArgumentException>())
|
willThrow<IllegalArgumentException>())
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.corda.core.flows
|
package net.corda.core.flows
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import com.natpryce.hamkrest.assertion.assert
|
import com.natpryce.hamkrest.assertion.assertThat
|
||||||
import net.corda.core.flows.mixins.WithMockNet
|
import net.corda.core.flows.mixins.WithMockNet
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.utilities.UntrustworthyData
|
import net.corda.core.utilities.UntrustworthyData
|
||||||
@ -10,11 +10,10 @@ import net.corda.testing.core.singleIdentity
|
|||||||
import net.corda.testing.internal.matchers.flow.willReturn
|
import net.corda.testing.internal.matchers.flow.willReturn
|
||||||
import net.corda.testing.node.internal.InternalMockNetwork
|
import net.corda.testing.node.internal.InternalMockNetwork
|
||||||
import net.corda.testing.node.internal.TestStartedNode
|
import net.corda.testing.node.internal.TestStartedNode
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
|
||||||
import org.junit.AfterClass
|
import org.junit.AfterClass
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class ReceiveMultipleFlowTests : WithMockNet {
|
class ReceiveMultipleFlowTests : WithMockNet {
|
||||||
companion object {
|
companion object {
|
||||||
@ -52,13 +51,13 @@ class ReceiveMultipleFlowTests : WithMockNet {
|
|||||||
// this is a closure, meaning you can access variables outside its scope e.g., `answer`.
|
// this is a closure, meaning you can access variables outside its scope e.g., `answer`.
|
||||||
val receivedMessage = session.receive<String>().unwrap { it }
|
val receivedMessage = session.receive<String>().unwrap { it }
|
||||||
logger.info("Got message from counterParty: $receivedMessage.")
|
logger.info("Got message from counterParty: $receivedMessage.")
|
||||||
assertThat(receivedMessage).isEqualTo(message)
|
assertEquals(message, receivedMessage)
|
||||||
session.send(answer)
|
session.send(answer)
|
||||||
}
|
}
|
||||||
} as FlowLogic<Unit>
|
} as FlowLogic<Unit>
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.that(
|
assertThat(
|
||||||
nodes[0].startFlowAndRunNetwork(initiatingFlow),
|
nodes[0].startFlowAndRunNetwork(initiatingFlow),
|
||||||
willReturn(answer as Any))
|
willReturn(answer as Any))
|
||||||
}
|
}
|
||||||
@ -70,7 +69,7 @@ class ReceiveMultipleFlowTests : WithMockNet {
|
|||||||
val stringValue = "Thriller"
|
val stringValue = "Thriller"
|
||||||
nodes[2].registerAnswer(AlgorithmDefinition::class, stringValue)
|
nodes[2].registerAnswer(AlgorithmDefinition::class, stringValue)
|
||||||
|
|
||||||
assert.that(
|
assertThat(
|
||||||
nodes[0].startFlowAndRunNetwork(ParallelAlgorithmMap(nodes[1].info.singleIdentity(), nodes[2].info.singleIdentity())),
|
nodes[0].startFlowAndRunNetwork(ParallelAlgorithmMap(nodes[1].info.singleIdentity(), nodes[2].info.singleIdentity())),
|
||||||
willReturn(doubleValue * stringValue.length))
|
willReturn(doubleValue * stringValue.length))
|
||||||
}
|
}
|
||||||
@ -82,7 +81,7 @@ class ReceiveMultipleFlowTests : WithMockNet {
|
|||||||
val value2 = 6.0
|
val value2 = 6.0
|
||||||
nodes[2].registerAnswer(ParallelAlgorithmList::class, value2)
|
nodes[2].registerAnswer(ParallelAlgorithmList::class, value2)
|
||||||
|
|
||||||
assert.that(
|
assertThat(
|
||||||
nodes[0].startFlowAndRunNetwork(ParallelAlgorithmList(nodes[1].info.singleIdentity(), nodes[2].info.singleIdentity())),
|
nodes[0].startFlowAndRunNetwork(ParallelAlgorithmList(nodes[1].info.singleIdentity(), nodes[2].info.singleIdentity())),
|
||||||
willReturn(listOf(value1, value2)))
|
willReturn(listOf(value1, value2)))
|
||||||
}
|
}
|
||||||
|
@ -107,8 +107,8 @@ class AttachmentsClassLoaderTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Test valid overlapping file condition`() {
|
fun `Test valid overlapping file condition`() {
|
||||||
val att1 = importAttachment(fakeAttachment("file1.txt", "same data").inputStream(), "app", "file1.jar")
|
val att1 = importAttachment(fakeAttachment("file1.txt", "same data", "file2.txt", "same other data" ).inputStream(), "app", "file1.jar")
|
||||||
val att2 = importAttachment(fakeAttachment("file1.txt", "same data").inputStream(), "app", "file2.jar")
|
val att2 = importAttachment(fakeAttachment("file1.txt", "same data", "file3.txt", "same totally different").inputStream(), "app", "file2.jar")
|
||||||
|
|
||||||
val cl = make(arrayOf(att1, att2).map { storage.openAttachment(it)!! })
|
val cl = make(arrayOf(att1, att2).map { storage.openAttachment(it)!! })
|
||||||
val txt = IOUtils.toString(cl.getResourceAsStream("file1.txt"), Charsets.UTF_8.name())
|
val txt = IOUtils.toString(cl.getResourceAsStream("file1.txt"), Charsets.UTF_8.name())
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.corda.core.utilities
|
package net.corda.core.utilities
|
||||||
|
|
||||||
import net.corda.core.crypto.AddressFormatException
|
import net.corda.core.crypto.AddressFormatException
|
||||||
import org.apache.commons.lang.ArrayUtils.EMPTY_BYTE_ARRAY
|
import org.apache.commons.lang3.ArrayUtils.EMPTY_BYTE_ARRAY
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.fail
|
import kotlin.test.fail
|
||||||
|
13
djvm/.gitignore
vendored
13
djvm/.gitignore
vendored
@ -1,13 +0,0 @@
|
|||||||
# DJVM-specific files
|
|
||||||
**/tmp/
|
|
||||||
*.log
|
|
||||||
*.log.gz
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
*.iml
|
|
||||||
*.ipr
|
|
||||||
*.iws
|
|
||||||
.idea/
|
|
||||||
|
|
||||||
**/out/
|
|
||||||
|
|
@ -1,120 +0,0 @@
|
|||||||
buildscript {
|
|
||||||
ext {
|
|
||||||
corda_djvm_version = '5.0-SNAPSHOT'
|
|
||||||
artifactory_contextUrl = 'https://ci-artifactory.corda.r3cev.com/artifactory'
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id 'net.corda.plugins.publish-utils' version '4.0.42' apply false
|
|
||||||
id 'com.github.johnrengelman.shadow' version '5.0.0' apply false
|
|
||||||
id 'com.jfrog.artifactory' version '4.7.3' apply false
|
|
||||||
id 'com.jfrog.bintray' version '1.4' apply false
|
|
||||||
id 'com.gradle.build-scan' version '2.2.1'
|
|
||||||
}
|
|
||||||
|
|
||||||
import static org.gradle.api.JavaVersion.*
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|
||||||
|
|
||||||
subprojects {
|
|
||||||
group 'net.corda'
|
|
||||||
version corda_djvm_version
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
jcenter()
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
|
||||||
sourceCompatibility = VERSION_1_8
|
|
||||||
targetCompatibility = VERSION_1_8
|
|
||||||
options.encoding = 'UTF-8'
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType(KotlinCompile) {
|
|
||||||
kotlinOptions {
|
|
||||||
languageVersion = '1.2'
|
|
||||||
apiVersion = '1.2'
|
|
||||||
jvmTarget = VERSION_1_8
|
|
||||||
javaParameters = true // Useful for reflection.
|
|
||||||
freeCompilerArgs = ['-Xjvm-default=enable']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType(Jar) { task ->
|
|
||||||
manifest {
|
|
||||||
attributes('Corda-Vendor': 'Corda Open Source')
|
|
||||||
attributes('Automatic-Module-Name': "net.corda.${task.project.name.replaceAll('-', '.')}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType(Test) {
|
|
||||||
// Prevent the project from creating temporary files outside of the build directory.
|
|
||||||
systemProperty 'java.io.tmpdir', buildDir.absolutePath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'net.corda.plugins.publish-utils'
|
|
||||||
apply plugin: 'com.jfrog.artifactory'
|
|
||||||
|
|
||||||
bintrayConfig {
|
|
||||||
user = System.getenv('CORDA_BINTRAY_USER')
|
|
||||||
key = System.getenv('CORDA_BINTRAY_KEY')
|
|
||||||
repo = 'corda'
|
|
||||||
org = 'r3'
|
|
||||||
licenses = ['Apache-2.0']
|
|
||||||
vcsUrl = 'https://github.com/corda/corda'
|
|
||||||
projectUrl = 'https://github.com/corda/corda'
|
|
||||||
gpgSign = true
|
|
||||||
gpgPassphrase = System.getenv('CORDA_BINTRAY_GPG_PASSPHRASE')
|
|
||||||
publications = [
|
|
||||||
'corda-djvm',
|
|
||||||
'corda-djvm-cli'
|
|
||||||
]
|
|
||||||
license {
|
|
||||||
name = 'Apache-2.0'
|
|
||||||
url = 'https://www.apache.org/licenses/LICENSE-2.0'
|
|
||||||
distribution = 'repo'
|
|
||||||
}
|
|
||||||
developer {
|
|
||||||
id = 'R3'
|
|
||||||
name = 'R3'
|
|
||||||
email = 'dev@corda.net'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
artifactory {
|
|
||||||
publish {
|
|
||||||
contextUrl = artifactory_contextUrl
|
|
||||||
repository {
|
|
||||||
repoKey = 'corda-dev'
|
|
||||||
username = System.getenv('CORDA_ARTIFACTORY_USERNAME')
|
|
||||||
password = System.getenv('CORDA_ARTIFACTORY_PASSWORD')
|
|
||||||
}
|
|
||||||
|
|
||||||
defaults {
|
|
||||||
// The root project has applied 'publish-utils' but has nothing to publish.
|
|
||||||
if (project != rootProject) {
|
|
||||||
publications(project.extensions.publish.name())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wrapper {
|
|
||||||
gradleVersion = "5.2.1"
|
|
||||||
distributionType = Wrapper.DistributionType.ALL
|
|
||||||
}
|
|
||||||
|
|
||||||
buildScan {
|
|
||||||
termsOfServiceUrl = 'https://gradle.com/terms-of-service'
|
|
||||||
termsOfServiceAgree = 'yes'
|
|
||||||
}
|
|
@ -1,87 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'org.jetbrains.kotlin.jvm'
|
|
||||||
id 'com.github.johnrengelman.shadow'
|
|
||||||
id 'net.corda.plugins.publish-utils'
|
|
||||||
id 'com.jfrog.artifactory'
|
|
||||||
id 'idea'
|
|
||||||
}
|
|
||||||
|
|
||||||
description 'Corda deterministic JVM sandbox'
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
url "$artifactory_contextUrl/corda-dev"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
configurations {
|
|
||||||
testImplementation.extendsFrom shadow
|
|
||||||
jdkRt.resolutionStrategy {
|
|
||||||
// Always check the repository for a newer SNAPSHOT.
|
|
||||||
cacheChangingModulesFor 0, 'seconds'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
shadow "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
|
||||||
shadow "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
|
||||||
shadow "org.slf4j:slf4j-api:$slf4j_version"
|
|
||||||
|
|
||||||
// ASM: byte code manipulation library
|
|
||||||
implementation "org.ow2.asm:asm:$asm_version"
|
|
||||||
implementation "org.ow2.asm:asm-commons:$asm_version"
|
|
||||||
|
|
||||||
// ClassGraph: classpath scanning
|
|
||||||
shadow "io.github.classgraph:classgraph:$class_graph_version"
|
|
||||||
|
|
||||||
// Test utilities
|
|
||||||
testImplementation "junit:junit:$junit_version"
|
|
||||||
testImplementation "org.assertj:assertj-core:$assertj_version"
|
|
||||||
testImplementation "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
|
|
||||||
jdkRt "net.corda:deterministic-rt:latest.integration"
|
|
||||||
}
|
|
||||||
|
|
||||||
jar.enabled = false
|
|
||||||
|
|
||||||
shadowJar {
|
|
||||||
baseName 'corda-djvm'
|
|
||||||
classifier ''
|
|
||||||
relocate 'org.objectweb.asm', 'djvm.org.objectweb.asm'
|
|
||||||
|
|
||||||
// These particular classes are only needed to "bootstrap"
|
|
||||||
// the compilation of the other sandbox classes. At runtime,
|
|
||||||
// we will generate better versions from deterministic-rt.jar.
|
|
||||||
exclude 'sandbox/java/lang/Appendable.class'
|
|
||||||
exclude 'sandbox/java/lang/CharSequence.class'
|
|
||||||
exclude 'sandbox/java/lang/Character\$Subset.class'
|
|
||||||
exclude 'sandbox/java/lang/Character\$Unicode*.class'
|
|
||||||
exclude 'sandbox/java/lang/Comparable.class'
|
|
||||||
exclude 'sandbox/java/lang/Enum.class'
|
|
||||||
exclude 'sandbox/java/lang/Iterable.class'
|
|
||||||
exclude 'sandbox/java/lang/StackTraceElement.class'
|
|
||||||
exclude 'sandbox/java/lang/StringBuffer.class'
|
|
||||||
exclude 'sandbox/java/lang/StringBuilder.class'
|
|
||||||
exclude 'sandbox/java/nio/**'
|
|
||||||
exclude 'sandbox/java/util/**'
|
|
||||||
}
|
|
||||||
assemble.dependsOn shadowJar
|
|
||||||
|
|
||||||
tasks.withType(Test) {
|
|
||||||
systemProperty 'deterministic-rt.path', configurations.jdkRt.asPath
|
|
||||||
}
|
|
||||||
|
|
||||||
artifacts {
|
|
||||||
publish shadowJar
|
|
||||||
}
|
|
||||||
|
|
||||||
publish {
|
|
||||||
dependenciesFrom configurations.shadow
|
|
||||||
name shadowJar.baseName
|
|
||||||
}
|
|
||||||
|
|
||||||
idea {
|
|
||||||
module {
|
|
||||||
downloadJavadoc = true
|
|
||||||
downloadSources = true
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'org.jetbrains.kotlin.jvm'
|
|
||||||
id 'com.github.johnrengelman.shadow'
|
|
||||||
id 'net.corda.plugins.publish-utils'
|
|
||||||
id 'com.jfrog.artifactory'
|
|
||||||
}
|
|
||||||
|
|
||||||
description 'Corda deterministic JVM sandbox command-line tool'
|
|
||||||
|
|
||||||
ext {
|
|
||||||
djvmName = 'corda-djvm-cli'
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-reflect"
|
|
||||||
implementation "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
|
|
||||||
implementation "org.apache.logging.log4j:log4j-core:$log4j_version"
|
|
||||||
implementation "com.jcabi:jcabi-manifests:$jcabi_manifests_version"
|
|
||||||
|
|
||||||
implementation "info.picocli:picocli:$picocli_version"
|
|
||||||
implementation project(path: ':djvm', configuration: 'shadow')
|
|
||||||
}
|
|
||||||
|
|
||||||
jar.enabled = false
|
|
||||||
|
|
||||||
shadowJar {
|
|
||||||
baseName djvmName
|
|
||||||
classifier ''
|
|
||||||
manifest {
|
|
||||||
attributes(
|
|
||||||
'Automatic-Module-Name': 'net.corda.djvm.cli',
|
|
||||||
'Main-Class': 'net.corda.djvm.tools.cli.Program',
|
|
||||||
'Build-Date': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
|
|
||||||
'Class-Path': 'tmp/'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task shadowZip(type: Zip) {
|
|
||||||
archiveBaseName = djvmName
|
|
||||||
archiveClassifier = ''
|
|
||||||
|
|
||||||
from(shadowJar) {
|
|
||||||
rename "$djvmName-(.*).jar", "${djvmName}.jar"
|
|
||||||
}
|
|
||||||
from('src/shell/') {
|
|
||||||
fileMode = 0755
|
|
||||||
}
|
|
||||||
zip64 true
|
|
||||||
}
|
|
||||||
|
|
||||||
assemble.dependsOn shadowZip
|
|
||||||
|
|
||||||
artifacts {
|
|
||||||
publish shadowZip
|
|
||||||
}
|
|
||||||
|
|
||||||
publish {
|
|
||||||
dependenciesFrom configurations.shadow
|
|
||||||
publishSources = false
|
|
||||||
publishJavadoc = false
|
|
||||||
name shadowZip.baseName
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package net.corda.djvm.tools.cli
|
|
||||||
|
|
||||||
import picocli.CommandLine.Command
|
|
||||||
import picocli.CommandLine.Parameters
|
|
||||||
import java.nio.file.Path
|
|
||||||
|
|
||||||
@Command(
|
|
||||||
name = "build",
|
|
||||||
description = ["Build one or more Java source files, each implementing the sandbox runnable interface " +
|
|
||||||
"required for execution in the deterministic sandbox."]
|
|
||||||
)
|
|
||||||
@Suppress("KDocMissingDocumentation")
|
|
||||||
class BuildCommand : CommandBase() {
|
|
||||||
|
|
||||||
@Parameters
|
|
||||||
var files: Array<Path> = emptyArray()
|
|
||||||
|
|
||||||
override fun validateArguments() = files.isNotEmpty()
|
|
||||||
|
|
||||||
override fun handleCommand(): Boolean {
|
|
||||||
val codePath = createCodePath()
|
|
||||||
val files = files.getFileNames { codePath.resolve(it) }
|
|
||||||
printVerbose("Compiling ${files.joinToString(", ")}...")
|
|
||||||
ProcessBuilder("javac", "-cp", "tmp:$jarPath", *files).apply {
|
|
||||||
inheritIO()
|
|
||||||
environment().putAll(System.getenv())
|
|
||||||
start().apply {
|
|
||||||
waitFor()
|
|
||||||
return (exitValue() == 0).apply {
|
|
||||||
if (this) {
|
|
||||||
printInfo("Build succeeded")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package net.corda.djvm.tools.cli
|
|
||||||
|
|
||||||
import net.corda.djvm.source.ClassSource
|
|
||||||
import picocli.CommandLine.Command
|
|
||||||
import picocli.CommandLine.Parameters
|
|
||||||
|
|
||||||
@Command(
|
|
||||||
name = "check",
|
|
||||||
description = ["Statically validate that a class or set of classes (and their dependencies) do not violate any " +
|
|
||||||
"constraints posed by the deterministic sandbox environment."]
|
|
||||||
)
|
|
||||||
@Suppress("KDocMissingDocumentation")
|
|
||||||
class CheckCommand : ClassCommand() {
|
|
||||||
|
|
||||||
override val filters: Array<String>
|
|
||||||
get() = classes
|
|
||||||
|
|
||||||
@Parameters(description = ["The partial or fully qualified names of the Java classes to analyse and validate."])
|
|
||||||
var classes: Array<String> = emptyArray()
|
|
||||||
|
|
||||||
override fun printSuccess(classes: List<Class<*>>) {
|
|
||||||
for (clazz in classes.sortedBy { it.name }) {
|
|
||||||
printVerbose("Class ${clazz.name} validated")
|
|
||||||
}
|
|
||||||
printVerbose()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun processClasses(classes: List<Class<*>>) {
|
|
||||||
val sources = classes.map { ClassSource.fromClassName(it.name) }
|
|
||||||
val summary = executor.validate(*sources.toTypedArray())
|
|
||||||
printMessages(summary.messages, summary.classOrigins)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,204 +0,0 @@
|
|||||||
package net.corda.djvm.tools.cli
|
|
||||||
|
|
||||||
import net.corda.djvm.SandboxConfiguration
|
|
||||||
import net.corda.djvm.analysis.AnalysisConfiguration
|
|
||||||
import net.corda.djvm.analysis.Whitelist
|
|
||||||
import net.corda.djvm.execution.*
|
|
||||||
import net.corda.djvm.references.ClassModule
|
|
||||||
import net.corda.djvm.source.ClassSource
|
|
||||||
import net.corda.djvm.source.SourceClassLoader
|
|
||||||
import net.corda.djvm.utilities.Discovery
|
|
||||||
import djvm.org.objectweb.asm.ClassReader
|
|
||||||
import picocli.CommandLine.Option
|
|
||||||
import java.nio.file.Files
|
|
||||||
import java.nio.file.Path
|
|
||||||
import java.nio.file.Paths
|
|
||||||
|
|
||||||
@Suppress("KDocMissingDocumentation", "MemberVisibilityCanBePrivate")
|
|
||||||
abstract class ClassCommand : CommandBase() {
|
|
||||||
|
|
||||||
@Option(
|
|
||||||
names = ["-p", "--profile"],
|
|
||||||
description = ["The execution profile to use (DEFAULT, UNLIMITED, DISABLE_BRANCHING or DISABLE_THROWS)."]
|
|
||||||
)
|
|
||||||
var profile: ExecutionProfile = ExecutionProfile.DEFAULT
|
|
||||||
|
|
||||||
@Option(names = ["--ignore-rules"], description = ["Disable all rules pertaining to the sandbox."])
|
|
||||||
var ignoreRules: Boolean = false
|
|
||||||
|
|
||||||
@Option(names = ["--ignore-emitters"], description = ["Disable all emitters defined for the sandbox."])
|
|
||||||
var ignoreEmitters: Boolean = false
|
|
||||||
|
|
||||||
@Option(names = ["--ignore-definition-providers"], description = ["Disable all definition providers."])
|
|
||||||
var ignoreDefinitionProviders: Boolean = false
|
|
||||||
|
|
||||||
@Option(names = ["-c", "--classpath"], description = ["Additions to the default class path."], split = ":")
|
|
||||||
var classPath: Array<Path> = emptyArray()
|
|
||||||
|
|
||||||
@Option(names = ["--disable-tracing"], description = ["Disable tracing in the sandbox."])
|
|
||||||
var disableTracing: Boolean = false
|
|
||||||
|
|
||||||
@Option(names = ["--analyze-annotations"], description = ["Analyze all annotations even if they are not " +
|
|
||||||
"explicitly referenced."])
|
|
||||||
var analyzeAnnotations: Boolean = false
|
|
||||||
|
|
||||||
@Option(
|
|
||||||
names = ["--prefix-filters"],
|
|
||||||
description = ["Only record messages matching one of the provided prefixes."],
|
|
||||||
split = ":"
|
|
||||||
)
|
|
||||||
var prefixFilters: Array<String> = emptyArray()
|
|
||||||
|
|
||||||
abstract val filters: Array<String>
|
|
||||||
|
|
||||||
private val classModule = ClassModule()
|
|
||||||
|
|
||||||
private lateinit var classLoader: ClassLoader
|
|
||||||
|
|
||||||
protected var executor = SandboxExecutor<Any, Any>(SandboxConfiguration.DEFAULT)
|
|
||||||
|
|
||||||
abstract fun processClasses(classes: List<Class<*>>)
|
|
||||||
|
|
||||||
open fun printSuccess(classes: List<Class<*>>) {}
|
|
||||||
|
|
||||||
override fun validateArguments() = filters.isNotEmpty()
|
|
||||||
|
|
||||||
override fun handleCommand(): Boolean {
|
|
||||||
val configuration = getConfiguration(Whitelist.MINIMAL)
|
|
||||||
classLoader = SourceClassLoader(getClasspath(), configuration.analysisConfiguration.classResolver)
|
|
||||||
createExecutor(configuration)
|
|
||||||
|
|
||||||
val classes = discoverClasses(filters).onEmpty {
|
|
||||||
throw Exception("Could not find any classes matching ${filters.joinToString(" ")} on the " +
|
|
||||||
"system class path")
|
|
||||||
}
|
|
||||||
|
|
||||||
return try {
|
|
||||||
processClasses(classes)
|
|
||||||
printSuccess(classes)
|
|
||||||
true
|
|
||||||
} catch (exception: Throwable) {
|
|
||||||
printException(exception)
|
|
||||||
if (exception is SandboxException) {
|
|
||||||
printCosts(exception.executionSummary.costs)
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun printCosts(costs: CostSummary) {
|
|
||||||
if (disableTracing) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
printInfo("Runtime Cost Summary:")
|
|
||||||
printInfo(" - allocations = @|yellow ${costs.allocations}|@")
|
|
||||||
printInfo(" - invocations = @|yellow ${costs.invocations}|@")
|
|
||||||
printInfo(" - jumps = @|yellow ${costs.jumps}|@")
|
|
||||||
printInfo(" - throws = @|yellow ${costs.throws}|@")
|
|
||||||
printInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun discoverClasses(filters: Array<String>): List<Class<*>> {
|
|
||||||
return findDiscoverableRunnables(filters) + findReferencedClasses(filters) + findClassesInJars(filters)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findDiscoverableRunnables(filters: Array<String>): List<Class<*>> {
|
|
||||||
val classes = find<java.util.function.Function<*,*>>()
|
|
||||||
val applicableFilters = filters
|
|
||||||
.filter { !isJarFile(it) && !isFullClassName(it) }
|
|
||||||
val filteredClasses = applicableFilters
|
|
||||||
.flatMap { filter ->
|
|
||||||
classes.filter { clazz ->
|
|
||||||
clazz.name.contains(filter, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (applicableFilters.isNotEmpty() && filteredClasses.isEmpty()) {
|
|
||||||
throw Exception("Could not find any classes implementing ${java.util.function.Function::class.java.simpleName} " +
|
|
||||||
"whose name matches '${applicableFilters.joinToString(" ")}'")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (applicableFilters.isNotEmpty()) {
|
|
||||||
printVerbose("Class path: $userClassPath")
|
|
||||||
printVerbose("Discovered runnables on the class path:")
|
|
||||||
for (clazz in classes) {
|
|
||||||
printVerbose(" - ${clazz.name}")
|
|
||||||
}
|
|
||||||
printVerbose()
|
|
||||||
}
|
|
||||||
return filteredClasses
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findReferencedClasses(filters: Array<String>): List<Class<*>> {
|
|
||||||
return filters.filter { !isJarFile(it) && isFullClassName(it) }.map {
|
|
||||||
val className = classModule.getFormattedClassName(it)
|
|
||||||
printVerbose("Looking up class $className...")
|
|
||||||
lookUpClass(className)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findClassesInJars(filters: Array<String>): List<Class<*>> {
|
|
||||||
return filters.filter { isJarFile(it) }.flatMap { jarFile ->
|
|
||||||
mutableListOf<Class<*>>().apply {
|
|
||||||
ClassSource.fromPath(Paths.get(jarFile)).getStreamIterator().forEach {
|
|
||||||
val reader = ClassReader(it)
|
|
||||||
val className = classModule.getFormattedClassName(reader.className)
|
|
||||||
printVerbose("Looking up class $className in $jarFile...")
|
|
||||||
this.add(lookUpClass(className))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun lookUpClass(className: String): Class<*> {
|
|
||||||
return try {
|
|
||||||
classLoader.loadClass(className)
|
|
||||||
} catch (exception: NoClassDefFoundError) {
|
|
||||||
val reference = exception.message?.let {
|
|
||||||
"referenced class ${classModule.getFormattedClassName(it)} in "
|
|
||||||
} ?: ""
|
|
||||||
throw Exception("Unable to load ${reference}type $className (is it present on the class path?)")
|
|
||||||
} catch (exception: TypeNotPresentException) {
|
|
||||||
val reference = exception.typeName() ?: ""
|
|
||||||
throw Exception("Type $reference not present in class $className")
|
|
||||||
} catch (exception: Throwable) {
|
|
||||||
throw Exception("Unable to load type $className (is it present on the class path?)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isJarFile(filter: String) = Files.exists(Paths.get(filter)) && filter.endsWith(".jar", true)
|
|
||||||
|
|
||||||
private fun isFullClassName(filter: String) = filter.count { it == '.' } > 0
|
|
||||||
|
|
||||||
private fun getClasspath() =
|
|
||||||
classPath.toList() + filters.filter { it.endsWith(".jar", true) }.map { Paths.get(it) }
|
|
||||||
|
|
||||||
private fun getConfiguration(whitelist: Whitelist): SandboxConfiguration {
|
|
||||||
return SandboxConfiguration.of(
|
|
||||||
profile = profile,
|
|
||||||
rules = if (ignoreRules) { emptyList() } else { Discovery.find() },
|
|
||||||
emitters = ignoreEmitters.emptyListIfTrueOtherwiseNull(),
|
|
||||||
definitionProviders = if (ignoreDefinitionProviders) { emptyList() } else { Discovery.find() },
|
|
||||||
enableTracing = !disableTracing,
|
|
||||||
analysisConfiguration = AnalysisConfiguration.createRoot(
|
|
||||||
whitelist = whitelist,
|
|
||||||
minimumSeverityLevel = level,
|
|
||||||
analyzeAnnotations = analyzeAnnotations,
|
|
||||||
prefixFilters = prefixFilters.toList(),
|
|
||||||
sourceClassLoaderFactory = { classResolver, bootstrapClassLoader ->
|
|
||||||
SourceClassLoader(getClasspath(), classResolver, bootstrapClassLoader)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createExecutor(configuration: SandboxConfiguration) {
|
|
||||||
executor = SandboxExecutor(configuration)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <T> Boolean.emptyListIfTrueOtherwiseNull(): List<T>? = when (this) {
|
|
||||||
true -> emptyList()
|
|
||||||
false -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,279 +0,0 @@
|
|||||||
package net.corda.djvm.tools.cli
|
|
||||||
|
|
||||||
import net.corda.djvm.analysis.Whitelist
|
|
||||||
import net.corda.djvm.execution.SandboxException
|
|
||||||
import net.corda.djvm.messages.MessageCollection
|
|
||||||
import net.corda.djvm.messages.Severity
|
|
||||||
import net.corda.djvm.references.ClassReference
|
|
||||||
import net.corda.djvm.references.EntityReference
|
|
||||||
import net.corda.djvm.references.MemberReference
|
|
||||||
import net.corda.djvm.rewiring.SandboxClassLoadingException
|
|
||||||
import org.apache.logging.log4j.Level
|
|
||||||
import org.apache.logging.log4j.core.config.Configurator
|
|
||||||
import picocli.CommandLine
|
|
||||||
import picocli.CommandLine.Help.Ansi
|
|
||||||
import picocli.CommandLine.Option
|
|
||||||
import java.nio.file.Path
|
|
||||||
import java.util.concurrent.Callable
|
|
||||||
|
|
||||||
@Suppress("KDocMissingDocumentation")
|
|
||||||
abstract class CommandBase : Callable<Boolean> {
|
|
||||||
|
|
||||||
@Option(
|
|
||||||
names = ["-l", "--level"],
|
|
||||||
description = ["The minimum severity level to log (TRACE, DEBUG, INFO, WARNING or ERROR."],
|
|
||||||
converter = [SeverityConverter::class]
|
|
||||||
)
|
|
||||||
protected var level: Severity = Severity.WARNING
|
|
||||||
|
|
||||||
@Option(
|
|
||||||
names = ["-q", "--quiet"],
|
|
||||||
description = ["Only print important messages to standard output."]
|
|
||||||
)
|
|
||||||
private var quiet: Boolean = false
|
|
||||||
|
|
||||||
@Option(
|
|
||||||
names = ["-v", "--verbose"],
|
|
||||||
description = ["Enable verbose logging."]
|
|
||||||
)
|
|
||||||
private var verbose: Boolean = false
|
|
||||||
|
|
||||||
@Option(
|
|
||||||
names = ["--debug"],
|
|
||||||
description = ["Print full stack traces upon error."]
|
|
||||||
)
|
|
||||||
private var debug: Boolean = false
|
|
||||||
|
|
||||||
@Option(
|
|
||||||
names = ["--colors"],
|
|
||||||
description = ["Use colors when printing to terminal."]
|
|
||||||
)
|
|
||||||
private var useColors: Boolean = false
|
|
||||||
|
|
||||||
@Option(
|
|
||||||
names = ["--no-colors"],
|
|
||||||
description = ["Do not use colors when printing to terminal."]
|
|
||||||
)
|
|
||||||
private var useNoColors: Boolean = false
|
|
||||||
|
|
||||||
@Option(
|
|
||||||
names = ["--compact"],
|
|
||||||
description = ["Print compact errors and warnings."]
|
|
||||||
)
|
|
||||||
private var compact: Boolean = false
|
|
||||||
|
|
||||||
@Option(
|
|
||||||
names = ["--print-origins"],
|
|
||||||
description = ["Print origins for errors and warnings."]
|
|
||||||
)
|
|
||||||
private var printOrigins: Boolean = false
|
|
||||||
|
|
||||||
private val ansi: Ansi
|
|
||||||
get() = when {
|
|
||||||
useNoColors -> Ansi.OFF
|
|
||||||
useColors -> Ansi.ON
|
|
||||||
else -> Ansi.AUTO
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class SeverityConverter : CommandLine.ITypeConverter<Severity> {
|
|
||||||
override fun convert(value: String): Severity {
|
|
||||||
return try {
|
|
||||||
when (value.toUpperCase()) {
|
|
||||||
"INFO" -> Severity.INFORMATIONAL
|
|
||||||
else -> Severity.valueOf(value.toUpperCase())
|
|
||||||
}
|
|
||||||
} catch (exception: Exception) {
|
|
||||||
val candidates = Severity.values().filter { it.name.startsWith(value, true) }
|
|
||||||
if (candidates.size == 1) {
|
|
||||||
candidates.first()
|
|
||||||
} else {
|
|
||||||
println("ERROR: Must be one of ${Severity.values().joinToString(", ") { it.name }}")
|
|
||||||
Severity.INFORMATIONAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun call(): Boolean {
|
|
||||||
if (!validateArguments()) {
|
|
||||||
CommandLine.usage(this, System.err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (verbose && quiet) {
|
|
||||||
printError("Error: Cannot set verbose and quiet modes at the same time")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
configureLogging()
|
|
||||||
return try {
|
|
||||||
handleCommand()
|
|
||||||
} catch (exception: Throwable) {
|
|
||||||
printException(exception)
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun configureLogging() {
|
|
||||||
val logLevel = when(level) {
|
|
||||||
Severity.ERROR -> Level.ERROR
|
|
||||||
Severity.WARNING -> Level.WARN
|
|
||||||
Severity.INFORMATIONAL -> Level.INFO
|
|
||||||
Severity.DEBUG -> Level.DEBUG
|
|
||||||
Severity.TRACE -> Level.TRACE
|
|
||||||
}
|
|
||||||
Configurator.setRootLevel(logLevel)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun printException(exception: Throwable) = when (exception) {
|
|
||||||
is SandboxClassLoadingException -> {
|
|
||||||
printMessages(exception.messages, exception.classOrigins)
|
|
||||||
printError()
|
|
||||||
}
|
|
||||||
is SandboxException -> {
|
|
||||||
val cause = exception.cause
|
|
||||||
when (cause) {
|
|
||||||
is SandboxClassLoadingException -> {
|
|
||||||
printMessages(cause.messages, cause.classOrigins)
|
|
||||||
printError()
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
if (debug) {
|
|
||||||
exception.exception.printStackTrace(System.err)
|
|
||||||
} else {
|
|
||||||
printError("Error: ${errorMessage(exception.exception)}")
|
|
||||||
}
|
|
||||||
printError()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
if (debug) {
|
|
||||||
exception.printStackTrace(System.err)
|
|
||||||
} else {
|
|
||||||
printError("Error: ${errorMessage(exception)}")
|
|
||||||
printError()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun errorMessage(exception: Throwable): String {
|
|
||||||
return when (exception) {
|
|
||||||
is StackOverflowError -> "Stack overflow"
|
|
||||||
is OutOfMemoryError -> "Out of memory"
|
|
||||||
is ThreadDeath -> "Thread death"
|
|
||||||
else -> {
|
|
||||||
val message = exception.message
|
|
||||||
when {
|
|
||||||
message.isNullOrBlank() -> exception.javaClass.simpleName
|
|
||||||
else -> message!!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun printMessages(messages: MessageCollection, origins: Map<String, Set<EntityReference>> = emptyMap()) {
|
|
||||||
val sortedMessages = messages.sorted()
|
|
||||||
val errorCount = messages.errorCount.countOf("error")
|
|
||||||
val warningCount = messages.warningCount.countOf("warning")
|
|
||||||
printInfo("Found $errorCount and $warningCount")
|
|
||||||
if (!compact) {
|
|
||||||
printInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
var first = true
|
|
||||||
for (message in sortedMessages) {
|
|
||||||
val severityColor = message.severity.color ?: "blue"
|
|
||||||
val location = message.location.format().let {
|
|
||||||
when {
|
|
||||||
it.isNotBlank() -> "in $it: "
|
|
||||||
else -> it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (compact) {
|
|
||||||
printError(" - @|$severityColor ${message.severity}|@ $location${message.message}.")
|
|
||||||
} else {
|
|
||||||
if (!first) {
|
|
||||||
printError()
|
|
||||||
}
|
|
||||||
printError(" - @|$severityColor ${message.severity}|@ $location\n ${message.message}.")
|
|
||||||
}
|
|
||||||
if (printOrigins) {
|
|
||||||
val classOrigins = origins[message.location.className.replace("/", ".")] ?: emptySet()
|
|
||||||
for (classOrigin in classOrigins.groupBy({ it.className }, { it })) {
|
|
||||||
val count = classOrigin.value.count()
|
|
||||||
val reference = when (count) {
|
|
||||||
1 -> classOrigin.value.first()
|
|
||||||
else -> ClassReference(classOrigin.value.first().className)
|
|
||||||
}
|
|
||||||
when (reference) {
|
|
||||||
is ClassReference ->
|
|
||||||
printError(" - Reference from ${reference.className}")
|
|
||||||
is MemberReference ->
|
|
||||||
printError(" - Reference from ${reference.className}.${reference.memberName}()")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printError()
|
|
||||||
}
|
|
||||||
first = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun handleCommand(): Boolean {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun validateArguments(): Boolean {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun printInfo(message: String = "") {
|
|
||||||
if (!quiet) {
|
|
||||||
println(ansi.Text(message).toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun printVerbose(message: String = "") {
|
|
||||||
if (verbose) {
|
|
||||||
println(ansi.Text(message).toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun printError(message: String = "") {
|
|
||||||
System.err.println(ansi.Text(message).toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun printResult(result: Any?) {
|
|
||||||
printInfo("Execution successful")
|
|
||||||
printInfo(" - result = $result")
|
|
||||||
printInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun whitelistFromPath(whitelist: Path?): Whitelist {
|
|
||||||
return whitelist?.let {
|
|
||||||
if ("$it" == "NONE") {
|
|
||||||
Whitelist.EMPTY
|
|
||||||
} else if ("$it" == "ALL") {
|
|
||||||
Whitelist.EVERYTHING
|
|
||||||
} else if ("$it" == "LANG") {
|
|
||||||
Whitelist.MINIMAL
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
Whitelist.fromFile(file = it)
|
|
||||||
} catch (exception: Throwable) {
|
|
||||||
throw Exception("Failed to load whitelist '$it'", exception)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} ?: Whitelist.MINIMAL
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Int.countOf(suffix: String): String {
|
|
||||||
return this.let {
|
|
||||||
when (it) {
|
|
||||||
0 -> "no ${suffix}s"
|
|
||||||
1 -> "@|yellow 1|@ $suffix"
|
|
||||||
else -> "@|yellow $it|@ ${suffix}s"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package net.corda.djvm.tools.cli
|
|
||||||
|
|
||||||
import picocli.CommandLine
|
|
||||||
import picocli.CommandLine.Command
|
|
||||||
|
|
||||||
@Command(
|
|
||||||
name = "djvm",
|
|
||||||
versionProvider = VersionProvider::class,
|
|
||||||
description = ["JVM for running programs in a deterministic sandbox."],
|
|
||||||
mixinStandardHelpOptions = true,
|
|
||||||
subcommands = [
|
|
||||||
BuildCommand::class,
|
|
||||||
CheckCommand::class,
|
|
||||||
InspectionCommand::class,
|
|
||||||
NewCommand::class,
|
|
||||||
RunCommand::class,
|
|
||||||
ShowCommand::class,
|
|
||||||
TreeCommand::class
|
|
||||||
]
|
|
||||||
)
|
|
||||||
@Suppress("KDocMissingDocumentation")
|
|
||||||
class Commands : CommandBase() {
|
|
||||||
|
|
||||||
fun run(args: Array<String>) = when (CommandLine.call(this, System.err, *args)) {
|
|
||||||
true -> 0
|
|
||||||
else -> 1
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,88 +0,0 @@
|
|||||||
package net.corda.djvm.tools.cli
|
|
||||||
|
|
||||||
import net.corda.djvm.source.ClassSource
|
|
||||||
import picocli.CommandLine.Command
|
|
||||||
import picocli.CommandLine.Parameters
|
|
||||||
import java.nio.file.Files
|
|
||||||
|
|
||||||
@Command(
|
|
||||||
name = "inspect",
|
|
||||||
description = ["Inspect the transformations that are being applied to classes before they get loaded into " +
|
|
||||||
"the sandbox."]
|
|
||||||
)
|
|
||||||
@Suppress("KDocMissingDocumentation")
|
|
||||||
class InspectionCommand : ClassCommand() {
|
|
||||||
|
|
||||||
override val filters: Array<String>
|
|
||||||
get() = classes
|
|
||||||
|
|
||||||
@Parameters(description = ["The partial or fully qualified names of the Java classes to inspect."])
|
|
||||||
var classes: Array<String> = emptyArray()
|
|
||||||
|
|
||||||
override fun processClasses(classes: List<Class<*>>) {
|
|
||||||
val sources = classes.map { ClassSource.fromClassName(it.name) }
|
|
||||||
val (_, messages) = executor.validate(*sources.toTypedArray())
|
|
||||||
|
|
||||||
if (messages.isNotEmpty()) {
|
|
||||||
for (message in messages.sorted()) {
|
|
||||||
printInfo(" - $message")
|
|
||||||
}
|
|
||||||
printInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
for (classSource in sources) {
|
|
||||||
val loadedClass = executor.load(classSource)
|
|
||||||
val sourceClass = createCodePath().resolve("${loadedClass.type.simpleName}.class")
|
|
||||||
val originalClass = Files.createTempFile("sandbox-", ".java")
|
|
||||||
val transformedClass = Files.createTempFile("sandbox-", ".java")
|
|
||||||
|
|
||||||
printInfo("Class: ${loadedClass.name}")
|
|
||||||
printVerbose(" - Size of the original byte code: ${Files.size(sourceClass)}")
|
|
||||||
printVerbose(" - Size of the transformed byte code: ${loadedClass.byteCode.bytes.size}")
|
|
||||||
printVerbose(" - Original class: $originalClass")
|
|
||||||
printVerbose(" - Transformed class: $transformedClass")
|
|
||||||
printInfo()
|
|
||||||
|
|
||||||
// Generate byte code dump of the original class
|
|
||||||
ProcessBuilder("javap", "-c", sourceClass.toString()).apply {
|
|
||||||
redirectOutput(originalClass.toFile())
|
|
||||||
environment().putAll(System.getenv())
|
|
||||||
start().apply {
|
|
||||||
waitFor()
|
|
||||||
exitValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate byte code dump of the transformed class
|
|
||||||
Files.createTempFile("sandbox-", ".class").apply {
|
|
||||||
Files.write(this, loadedClass.byteCode.bytes)
|
|
||||||
ProcessBuilder("javap", "-c", this.toString()).apply {
|
|
||||||
redirectOutput(transformedClass.toFile())
|
|
||||||
environment().putAll(System.getenv())
|
|
||||||
start().apply {
|
|
||||||
waitFor()
|
|
||||||
exitValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Files.delete(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate and display the difference between the original and the transformed class
|
|
||||||
ProcessBuilder(
|
|
||||||
"git", "diff", originalClass.toString(), transformedClass.toString()
|
|
||||||
).apply {
|
|
||||||
inheritIO()
|
|
||||||
environment().putAll(System.getenv())
|
|
||||||
start().apply {
|
|
||||||
waitFor()
|
|
||||||
exitValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printInfo()
|
|
||||||
|
|
||||||
Files.deleteIfExists(originalClass)
|
|
||||||
Files.deleteIfExists(transformedClass)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
package net.corda.djvm.tools.cli
|
|
||||||
|
|
||||||
import picocli.CommandLine.*
|
|
||||||
import java.nio.file.Files
|
|
||||||
import java.nio.file.Path
|
|
||||||
|
|
||||||
@Command(
|
|
||||||
name = "new",
|
|
||||||
description = ["Create one or more new Java classes implementing the sandbox runnable interface that is " +
|
|
||||||
"required for execution in the deterministic sandbox. Each Java file is created using a template, " +
|
|
||||||
"with class name derived from the provided file name."
|
|
||||||
],
|
|
||||||
showDefaultValues = true
|
|
||||||
)
|
|
||||||
@Suppress("KDocMissingDocumentation")
|
|
||||||
class NewCommand : CommandBase() {
|
|
||||||
|
|
||||||
@Parameters(description = ["The names of the Java source files that will be created."])
|
|
||||||
var files: Array<Path> = emptyArray()
|
|
||||||
|
|
||||||
@Option(names = ["-f", "--force"], description = ["Forcefully overwrite files if they already exist."])
|
|
||||||
var force: Boolean = false
|
|
||||||
|
|
||||||
@Option(names = ["--from"], description = ["The input type to use for the constructed runnable."])
|
|
||||||
var fromType: String = "Object"
|
|
||||||
|
|
||||||
@Option(names = ["--to"], description = ["The output type to use for the constructed runnable."])
|
|
||||||
var toType: String = "Object"
|
|
||||||
|
|
||||||
@Option(names = ["--return"], description = ["The default return value for the constructed runnable."])
|
|
||||||
var returnValue: String = "null"
|
|
||||||
|
|
||||||
override fun validateArguments() = files.isNotEmpty()
|
|
||||||
|
|
||||||
override fun handleCommand(): Boolean {
|
|
||||||
val codePath = createCodePath()
|
|
||||||
val files = files.getFiles { codePath.resolve(it) }
|
|
||||||
for (file in files) {
|
|
||||||
try {
|
|
||||||
printVerbose("Creating file '$file'...")
|
|
||||||
Files.newBufferedWriter(file, *openOptions(force)).use {
|
|
||||||
it.append(TEMPLATE
|
|
||||||
.replace("[NAME]", file.baseName)
|
|
||||||
.replace("[FROM]", fromType)
|
|
||||||
.replace("[TO]", toType)
|
|
||||||
.replace("[RETURN]", returnValue))
|
|
||||||
}
|
|
||||||
} catch (exception: Throwable) {
|
|
||||||
throw Exception("Failed to create file '$file'", exception)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
val TEMPLATE = """
|
|
||||||
|package net.corda.sandbox;
|
|
||||||
|
|
|
||||||
|import java.util.function.Function;
|
|
||||||
|
|
|
||||||
|public class [NAME] implements Function<[FROM], [TO]> {
|
|
||||||
| @Override
|
|
||||||
| public [TO] apply([FROM] input) {
|
|
||||||
| return [RETURN];
|
|
||||||
| }
|
|
||||||
|}
|
|
||||||
""".trimMargin()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
@file:JvmName("Program")
|
|
||||||
|
|
||||||
package net.corda.djvm.tools.cli
|
|
||||||
|
|
||||||
import kotlin.system.exitProcess
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The entry point of the deterministic sandbox tool.
|
|
||||||
*/
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
exitProcess(Commands().run(args))
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package net.corda.djvm.tools.cli
|
|
||||||
|
|
||||||
import net.corda.djvm.source.ClassSource
|
|
||||||
import picocli.CommandLine.Command
|
|
||||||
import picocli.CommandLine.Parameters
|
|
||||||
|
|
||||||
@Command(
|
|
||||||
name = "run",
|
|
||||||
description = ["Execute runnable in sandbox."],
|
|
||||||
showDefaultValues = true
|
|
||||||
)
|
|
||||||
@Suppress("KDocMissingDocumentation")
|
|
||||||
class RunCommand : ClassCommand() {
|
|
||||||
|
|
||||||
override val filters: Array<String>
|
|
||||||
get() = classes
|
|
||||||
|
|
||||||
@Parameters(description = ["The partial or fully qualified names of the Java classes to run."])
|
|
||||||
var classes: Array<String> = emptyArray()
|
|
||||||
|
|
||||||
override fun processClasses(classes: List<Class<*>>) {
|
|
||||||
val interfaceName = java.util.function.Function::class.java.simpleName
|
|
||||||
for (clazz in classes) {
|
|
||||||
if (!clazz.interfaces.any { it.simpleName == interfaceName }) {
|
|
||||||
printError("Class is not an instance of $interfaceName; ${clazz.name}")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
printInfo("Running class ${clazz.name}...")
|
|
||||||
executor.run(ClassSource.fromClassName(clazz.name), Any()).apply {
|
|
||||||
printResult(result)
|
|
||||||
printCosts(costs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
package net.corda.djvm.tools.cli
|
|
||||||
|
|
||||||
import net.corda.djvm.source.ClassSource
|
|
||||||
import picocli.CommandLine.Command
|
|
||||||
import picocli.CommandLine.Parameters
|
|
||||||
import java.nio.file.Files
|
|
||||||
|
|
||||||
@Command(
|
|
||||||
name = "show",
|
|
||||||
description = ["Show the transformed version of a class as it is prepared for execution in the deterministic " +
|
|
||||||
"sandbox."]
|
|
||||||
)
|
|
||||||
@Suppress("KDocMissingDocumentation")
|
|
||||||
class ShowCommand : ClassCommand() {
|
|
||||||
|
|
||||||
override val filters: Array<String>
|
|
||||||
get() = classes
|
|
||||||
|
|
||||||
@Parameters(description = ["The partial or fully qualified names of the Java classes to inspect."])
|
|
||||||
var classes: Array<String> = emptyArray()
|
|
||||||
|
|
||||||
override fun processClasses(classes: List<Class<*>>) {
|
|
||||||
val sources = classes.map { ClassSource.fromClassName(it.name) }
|
|
||||||
val (_, messages) = executor.validate(*sources.toTypedArray())
|
|
||||||
|
|
||||||
if (messages.isNotEmpty()) {
|
|
||||||
for (message in messages.sorted()) {
|
|
||||||
printInfo(" - $message")
|
|
||||||
}
|
|
||||||
printInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
for (classSource in sources) {
|
|
||||||
val loadedClass = executor.load(classSource)
|
|
||||||
printInfo("Class: ${loadedClass.name}")
|
|
||||||
printVerbose(" - Byte code size: ${loadedClass.byteCode.bytes.size}")
|
|
||||||
printVerbose(" - Has been modified: ${loadedClass.byteCode.isModified}")
|
|
||||||
printInfo()
|
|
||||||
|
|
||||||
Files.createTempFile("sandbox-", ".class").apply {
|
|
||||||
Files.write(this, loadedClass.byteCode.bytes)
|
|
||||||
ProcessBuilder("javap", "-c", this.toString()).apply {
|
|
||||||
inheritIO()
|
|
||||||
environment().putAll(System.getenv())
|
|
||||||
start().apply {
|
|
||||||
waitFor()
|
|
||||||
exitValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Files.delete(this)
|
|
||||||
}
|
|
||||||
printInfo()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package net.corda.djvm.tools.cli
|
|
||||||
|
|
||||||
import picocli.CommandLine.Command
|
|
||||||
import java.nio.file.Files
|
|
||||||
|
|
||||||
@Command(
|
|
||||||
name = "tree",
|
|
||||||
description = ["Show the hierarchy of the classes that have been created with the 'new' command."]
|
|
||||||
)
|
|
||||||
@Suppress("KDocMissingDocumentation")
|
|
||||||
class TreeCommand : CommandBase() {
|
|
||||||
|
|
||||||
override fun validateArguments() = true
|
|
||||||
|
|
||||||
override fun handleCommand(): Boolean {
|
|
||||||
val path = workingDirectory.resolve("tmp")
|
|
||||||
if (!Files.exists(path)) {
|
|
||||||
printError("No classes have been created so far. Run `djvm new` to get started.")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
ProcessBuilder("find", ".", "-type", "f").apply {
|
|
||||||
inheritIO()
|
|
||||||
environment().putAll(System.getenv())
|
|
||||||
directory(path.toFile())
|
|
||||||
start().apply {
|
|
||||||
waitFor()
|
|
||||||
exitValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,102 +0,0 @@
|
|||||||
@file:JvmName("Utilities")
|
|
||||||
package net.corda.djvm.tools.cli
|
|
||||||
|
|
||||||
import io.github.classgraph.ClassGraph
|
|
||||||
import java.lang.reflect.Modifier.isAbstract
|
|
||||||
import java.lang.reflect.Modifier.isStatic
|
|
||||||
import java.nio.file.Files
|
|
||||||
import java.nio.file.Path
|
|
||||||
import java.nio.file.Paths
|
|
||||||
import java.nio.file.StandardOpenOption
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the expanded file name of each path in the provided array.
|
|
||||||
*/
|
|
||||||
fun Array<Path>?.getFiles(map: (Path) -> Path = { it }) = (this ?: emptyArray()).map {
|
|
||||||
val pathString = it.toString()
|
|
||||||
val path = map(it)
|
|
||||||
when {
|
|
||||||
'/' in pathString || '\\' in pathString ->
|
|
||||||
throw Exception("Please provide a pathless file name")
|
|
||||||
pathString.endsWith(".java", true) -> path
|
|
||||||
else -> Paths.get("$path.java")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the string representation of each expanded file name in the provided array.
|
|
||||||
*/
|
|
||||||
fun Array<Path>?.getFileNames(map: (Path) -> Path = { it }) = this.getFiles(map).map {
|
|
||||||
it.toString()
|
|
||||||
}.toTypedArray()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute inlined action if the collection is empty.
|
|
||||||
*/
|
|
||||||
inline fun <T> List<T>.onEmpty(action: () -> Unit): List<T> {
|
|
||||||
if (!this.any()) {
|
|
||||||
action()
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute inlined action if the array is empty.
|
|
||||||
*/
|
|
||||||
inline fun <reified T> Array<T>?.onEmpty(action: () -> Unit): Array<T> {
|
|
||||||
return (this ?: emptyArray()).toList().onEmpty(action).toTypedArray()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Derive the set of [StandardOpenOption]'s to use for a file operation.
|
|
||||||
*/
|
|
||||||
fun openOptions(force: Boolean) = if (force) {
|
|
||||||
arrayOf(StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)
|
|
||||||
} else {
|
|
||||||
arrayOf(StandardOpenOption.CREATE_NEW)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the path of where any generated code will be placed. Create the directory if it does not exist.
|
|
||||||
*/
|
|
||||||
fun createCodePath(): Path {
|
|
||||||
return Paths.get("tmp", "net", "corda", "sandbox").let {
|
|
||||||
Files.createDirectories(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the base name of a file (i.e., its name without extension)
|
|
||||||
*/
|
|
||||||
val Path.baseName: String
|
|
||||||
get() = this.fileName.toString()
|
|
||||||
.replaceAfterLast('.', "")
|
|
||||||
.removeSuffix(".")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The path of the executing JAR.
|
|
||||||
*/
|
|
||||||
val jarPath: String = object {}.javaClass.protectionDomain.codeSource.location.toURI().path
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The path of the current working directory.
|
|
||||||
*/
|
|
||||||
val workingDirectory: Path = Paths.get(System.getProperty("user.dir"))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The class path for the current execution context.
|
|
||||||
*/
|
|
||||||
val userClassPath: String = System.getProperty("java.class.path")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a reference of each concrete class that implements interface or class [T].
|
|
||||||
*/
|
|
||||||
inline fun <reified T> find(scanSpec: String = "net/corda/sandbox"): List<Class<*>> {
|
|
||||||
return ClassGraph()
|
|
||||||
.whitelistPaths(scanSpec)
|
|
||||||
.enableAllInfo()
|
|
||||||
.scan()
|
|
||||||
.use { it.getClassesImplementing(T::class.java.name).loadClasses(T::class.java) }
|
|
||||||
.filter { !isAbstract(it.modifiers) && !isStatic(it.modifiers) }
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
package net.corda.djvm.tools.cli
|
|
||||||
|
|
||||||
import com.jcabi.manifests.Manifests
|
|
||||||
import picocli.CommandLine.IVersionProvider
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the version number to use for the tool.
|
|
||||||
*/
|
|
||||||
@Suppress("KDocMissingDocumentation")
|
|
||||||
class VersionProvider : IVersionProvider {
|
|
||||||
override fun getVersion(): Array<String> = arrayOf(
|
|
||||||
Manifests.read("Corda-Release-Version")
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Configuration status="info">
|
|
||||||
|
|
||||||
<ThresholdFilter level="trace"/>
|
|
||||||
<Appenders>
|
|
||||||
<!-- Will generate up to 10 log files for a given day. During every rollover it will delete
|
|
||||||
those that are older than 60 days, but keep the most recent 10 GB -->
|
|
||||||
<RollingFile name="RollingFile-Appender"
|
|
||||||
fileName="djvm.log"
|
|
||||||
filePattern="djvm.%date{yyyy-MM-dd}-%i.log.gz">
|
|
||||||
|
|
||||||
<PatternLayout pattern="%date{ISO8601}{UTC}Z [%-5level] %c - %msg%n"/>
|
|
||||||
|
|
||||||
<Policies>
|
|
||||||
<TimeBasedTriggeringPolicy/>
|
|
||||||
<SizeBasedTriggeringPolicy size="10MB"/>
|
|
||||||
</Policies>
|
|
||||||
|
|
||||||
<DefaultRolloverStrategy min="1" max="10">
|
|
||||||
<Delete basePath="" maxDepth="1">
|
|
||||||
<IfFileName glob="djvm*.log.gz"/>
|
|
||||||
<IfLastModified age="60d">
|
|
||||||
<IfAny>
|
|
||||||
<IfAccumulatedFileSize exceeds="10 GB"/>
|
|
||||||
</IfAny>
|
|
||||||
</IfLastModified>
|
|
||||||
</Delete>
|
|
||||||
</DefaultRolloverStrategy>
|
|
||||||
|
|
||||||
</RollingFile>
|
|
||||||
</Appenders>
|
|
||||||
|
|
||||||
<Loggers>
|
|
||||||
<Root level="info">
|
|
||||||
<AppenderRef ref="RollingFile-Appender"/>
|
|
||||||
</Root>
|
|
||||||
</Loggers>
|
|
||||||
|
|
||||||
</Configuration>
|
|
@ -1,16 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
SCRIPT_DIR=$(dirname $(readlink -f ${BASH_SOURCE[0]}))
|
|
||||||
|
|
||||||
CLASSPATH="${CLASSPATH:-}"
|
|
||||||
|
|
||||||
DEBUG=`echo "${DEBUG:-0}" | sed 's/^[Nn][Oo]*$/0/g'`
|
|
||||||
DEBUG_PORT=5005
|
|
||||||
DEBUG_AGENT=""
|
|
||||||
|
|
||||||
if [ "$DEBUG" != 0 ]; then
|
|
||||||
echo "Opening remote debugging session on port $DEBUG_PORT"
|
|
||||||
DEBUG_AGENT="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=$DEBUG_PORT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec java $DEBUG_AGENT -cp "$CLASSPATH:.:tmp:$SCRIPT_DIR/corda-djvm-cli.jar" net.corda.djvm.tools.cli.Program "$@"
|
|
@ -1,15 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
|
|
||||||
SETLOCAL ENABLEEXTENSIONS
|
|
||||||
|
|
||||||
IF NOT DEFINED CLASSPATH (SET CLASSPATH=)
|
|
||||||
|
|
||||||
IF DEFINED DEBUG (
|
|
||||||
SET DEBUG_PORT=5005
|
|
||||||
SET DEBUG_AGENT=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=%DEBUG_PORT%
|
|
||||||
ECHO Opening remote debugging session on port %DEBUG_PORT%
|
|
||||||
) ELSE (
|
|
||||||
SET DEBUG_AGENT=
|
|
||||||
)
|
|
||||||
|
|
||||||
CALL java %DEBUG_AGENT% -cp "%CLASSPATH%;.;tmp;%~dp0\corda-djvm-cli.jar" net.corda.djvm.tools.cli.Program %*
|
|
@ -1,7 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
SCRIPT_DIR=$(dirname $(readlink -f ${BASH_SOURCE[0]}))
|
|
||||||
|
|
||||||
# Generate auto-completion file for Bash and ZSH
|
|
||||||
java -cp ${SCRIPT_DIR}/corda-djvm-cli.jar \
|
|
||||||
picocli.AutoComplete -n djvm net.corda.djvm.tools.cli.Commands -f
|
|
1
djvm/djvm/shell/.gitignore
vendored
1
djvm/djvm/shell/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
djvm_completion
|
|
@ -1,19 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
file="${BASH_SOURCE[0]}"
|
|
||||||
linked_file="$(test -L "$file" && readlink "$file" || echo "$file")"
|
|
||||||
base_dir="$(cd "$(dirname "$linked_file")/../" && pwd)"
|
|
||||||
djvm_cli_jar=$(ls -1 $base_dir/cli/build/libs/corda-djvm-cli-*.jar)
|
|
||||||
|
|
||||||
CLASSPATH="${CLASSPATH:-}"
|
|
||||||
|
|
||||||
DEBUG=`echo "${DEBUG:-0}" | sed 's/^[Nn][Oo]*$/0/g'`
|
|
||||||
DEBUG_PORT=5005
|
|
||||||
DEBUG_AGENT=""
|
|
||||||
|
|
||||||
if [ "$DEBUG" != 0 ]; then
|
|
||||||
echo "Opening remote debugging session on port $DEBUG_PORT"
|
|
||||||
DEBUG_AGENT="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=$DEBUG_PORT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
java $DEBUG_AGENT -cp "$CLASSPATH:.:tmp:$djvm_cli_jar" net.corda.djvm.tools.cli.Program "$@"
|
|
@ -1,24 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
file="${BASH_SOURCE[0]}"
|
|
||||||
base_dir="$(cd "$(dirname "$file")/" && pwd)"
|
|
||||||
|
|
||||||
# Build DJVM module and CLI
|
|
||||||
cd "$base_dir/.."
|
|
||||||
if !(../gradlew shadowJar); then
|
|
||||||
echo "Failed to build DJVM"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
djvm_cli_jar=$(ls -1 $base_dir/../cli/build/libs/corda-djvm-cli-*.jar)
|
|
||||||
|
|
||||||
# Generate auto-completion file for Bash and ZSH
|
|
||||||
cd "$base_dir"
|
|
||||||
if !(java -cp $djvm_cli_jar \
|
|
||||||
picocli.AutoComplete -n djvm net.corda.djvm.tools.cli.Commands -f); then
|
|
||||||
echo "Failed to generate auto-completion file"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create a symbolic link to the `djvm` utility
|
|
||||||
sudo ln -sf "$base_dir/djvm" /usr/local/bin/djvm
|
|
@ -1,19 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class that implements just enough of {@link java.lang.Appendable}
|
|
||||||
* to keep {@link sandbox.java.lang.StringBuilder}, {@link sandbox.java.lang.StringBuffer}
|
|
||||||
* and {@link sandbox.java.lang.String} honest.
|
|
||||||
* Note that it does not extend {@link java.lang.Appendable}.
|
|
||||||
*/
|
|
||||||
public interface Appendable {
|
|
||||||
|
|
||||||
Appendable append(CharSequence csq, int start, int end) throws IOException;
|
|
||||||
|
|
||||||
Appendable append(CharSequence csq) throws IOException;
|
|
||||||
|
|
||||||
Appendable append(char c) throws IOException;
|
|
||||||
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
||||||
public final class Boolean extends Object implements Comparable<Boolean>, Serializable {
|
|
||||||
|
|
||||||
public static final Boolean TRUE = new Boolean(true);
|
|
||||||
public static final Boolean FALSE = new Boolean(false);
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static final Class<Boolean> TYPE = (Class) java.lang.Boolean.TYPE;
|
|
||||||
|
|
||||||
private final boolean value;
|
|
||||||
|
|
||||||
public Boolean(boolean value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean(String s) {
|
|
||||||
this(parseBoolean(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(java.lang.Object other) {
|
|
||||||
return (other instanceof Boolean) && ((Boolean) other).value == value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return hashCode(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int hashCode(boolean value) {
|
|
||||||
return java.lang.Boolean.hashCode(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean booleanValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public java.lang.String toString() {
|
|
||||||
return java.lang.Boolean.toString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public String toDJVMString() {
|
|
||||||
return toString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toString(boolean b) {
|
|
||||||
return String.valueOf(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
java.lang.Boolean fromDJVM() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NotNull Boolean other) {
|
|
||||||
return compare(value, other.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int compare(boolean x, boolean y) {
|
|
||||||
return java.lang.Boolean.compare(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean parseBoolean(String s) {
|
|
||||||
return java.lang.Boolean.parseBoolean(String.fromDJVM(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean valueOf(boolean b) {
|
|
||||||
return b ? TRUE : FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean valueOf(String s) {
|
|
||||||
return valueOf(parseBoolean(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean logicalAnd(boolean a, boolean b) {
|
|
||||||
return java.lang.Boolean.logicalAnd(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean logicalOr(boolean a, boolean b) {
|
|
||||||
return java.lang.Boolean.logicalOr(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean logicalXor(boolean a, boolean b) {
|
|
||||||
return java.lang.Boolean.logicalXor(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean toDJVM(java.lang.Boolean b) { return (b == null) ? null : new Boolean(b); }
|
|
||||||
}
|
|
@ -1,129 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
||||||
public final class Byte extends Number implements Comparable<Byte> {
|
|
||||||
public static final byte MIN_VALUE = java.lang.Byte.MIN_VALUE;
|
|
||||||
public static final byte MAX_VALUE = java.lang.Byte.MAX_VALUE;
|
|
||||||
public static final int BYTES = java.lang.Byte.BYTES;
|
|
||||||
public static final int SIZE = java.lang.Byte.SIZE;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static final Class<Byte> TYPE = (Class) java.lang.Byte.TYPE;
|
|
||||||
|
|
||||||
private final byte value;
|
|
||||||
|
|
||||||
public Byte(byte value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Byte(String s) throws NumberFormatException {
|
|
||||||
this.value = parseByte(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte byteValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short shortValue() {
|
|
||||||
return (short) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int intValue() {
|
|
||||||
return (int) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long longValue() {
|
|
||||||
return (long) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float floatValue() {
|
|
||||||
return (float) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double doubleValue() {
|
|
||||||
return (double) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return hashCode(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int hashCode(byte b) {
|
|
||||||
return java.lang.Byte.hashCode(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(java.lang.Object other) {
|
|
||||||
return (other instanceof Byte) && ((Byte) other).value == value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public java.lang.String toString() {
|
|
||||||
return java.lang.Byte.toString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
java.lang.Byte fromDJVM() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NotNull Byte other) {
|
|
||||||
return compare(this.value, other.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int compare(byte x, byte y) {
|
|
||||||
return java.lang.Byte.compare(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toString(byte b) {
|
|
||||||
return Integer.toString(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Byte valueOf(byte b) {
|
|
||||||
return new Byte(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte parseByte(String s, int radix) throws NumberFormatException {
|
|
||||||
return java.lang.Byte.parseByte(String.fromDJVM(s), radix);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte parseByte(String s) throws NumberFormatException {
|
|
||||||
return java.lang.Byte.parseByte(String.fromDJVM(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Byte valueOf(String s, int radix) throws NumberFormatException {
|
|
||||||
return toDJVM(java.lang.Byte.valueOf(String.fromDJVM(s), radix));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Byte valueOf(String s) throws NumberFormatException {
|
|
||||||
return toDJVM(java.lang.Byte.valueOf(String.fromDJVM(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Byte decode(String s) throws NumberFormatException {
|
|
||||||
return toDJVM(java.lang.Byte.decode(String.fromDJVM(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int toUnsignedInt(byte b) {
|
|
||||||
return java.lang.Byte.toUnsignedInt(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long toUnsignedLong(byte b) {
|
|
||||||
return java.lang.Byte.toUnsignedLong(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Byte toDJVM(java.lang.Byte b) {
|
|
||||||
return (b == null) ? null : valueOf(b);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class that implements just enough of {@link java.lang.CharSequence}
|
|
||||||
* to allow us to compile {@link sandbox.java.lang.String}.
|
|
||||||
*/
|
|
||||||
public interface CharSequence extends java.lang.CharSequence {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
CharSequence subSequence(int start, int end);
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
String toDJVMString();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
java.lang.String toString();
|
|
||||||
|
|
||||||
}
|
|
@ -1,481 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
||||||
public final class Character extends Object implements Comparable<Character>, Serializable {
|
|
||||||
public static final int MIN_RADIX = java.lang.Character.MIN_RADIX;
|
|
||||||
public static final int MAX_RADIX = java.lang.Character.MAX_RADIX;
|
|
||||||
public static final char MIN_VALUE = java.lang.Character.MIN_VALUE;
|
|
||||||
public static final char MAX_VALUE = java.lang.Character.MAX_VALUE;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static final Class<Character> TYPE = (Class) java.lang.Character.TYPE;
|
|
||||||
|
|
||||||
public static final byte UNASSIGNED = java.lang.Character.UNASSIGNED;
|
|
||||||
public static final byte UPPERCASE_LETTER = java.lang.Character.UPPERCASE_LETTER;
|
|
||||||
public static final byte LOWERCASE_LETTER = java.lang.Character.LOWERCASE_LETTER;
|
|
||||||
public static final byte TITLECASE_LETTER = java.lang.Character.TITLECASE_LETTER;
|
|
||||||
public static final byte MODIFIER_LETTER = java.lang.Character.MODIFIER_LETTER;
|
|
||||||
public static final byte OTHER_LETTER = java.lang.Character.OTHER_LETTER;
|
|
||||||
public static final byte NON_SPACING_MARK = java.lang.Character.NON_SPACING_MARK;
|
|
||||||
public static final byte ENCLOSING_MARK = java.lang.Character.ENCLOSING_MARK;
|
|
||||||
public static final byte COMBINING_SPACING_MARK = java.lang.Character.COMBINING_SPACING_MARK;
|
|
||||||
public static final byte DECIMAL_DIGIT_NUMBER = java.lang.Character.DECIMAL_DIGIT_NUMBER;
|
|
||||||
public static final byte LETTER_NUMBER = java.lang.Character.LETTER_NUMBER;
|
|
||||||
public static final byte OTHER_NUMBER = java.lang.Character.OTHER_NUMBER;
|
|
||||||
public static final byte SPACE_SEPARATOR = java.lang.Character.SPACE_SEPARATOR;
|
|
||||||
public static final byte LINE_SEPARATOR = java.lang.Character.LINE_SEPARATOR;
|
|
||||||
public static final byte PARAGRAPH_SEPARATOR = java.lang.Character.PARAGRAPH_SEPARATOR;
|
|
||||||
public static final byte CONTROL = java.lang.Character.CONTROL;
|
|
||||||
public static final byte FORMAT = java.lang.Character.FORMAT;
|
|
||||||
public static final byte PRIVATE_USE = java.lang.Character.PRIVATE_USE;
|
|
||||||
public static final byte SURROGATE = java.lang.Character.SURROGATE;
|
|
||||||
public static final byte DASH_PUNCTUATION = java.lang.Character.DASH_PUNCTUATION;
|
|
||||||
public static final byte START_PUNCTUATION = java.lang.Character.START_PUNCTUATION;
|
|
||||||
public static final byte END_PUNCTUATION = java.lang.Character.END_PUNCTUATION;
|
|
||||||
public static final byte CONNECTOR_PUNCTUATION = java.lang.Character.CONNECTOR_PUNCTUATION;
|
|
||||||
public static final byte OTHER_PUNCTUATION = java.lang.Character.OTHER_PUNCTUATION;
|
|
||||||
public static final byte MATH_SYMBOL = java.lang.Character.MATH_SYMBOL;
|
|
||||||
public static final byte CURRENCY_SYMBOL = java.lang.Character.CURRENCY_SYMBOL;
|
|
||||||
public static final byte MODIFIER_SYMBOL = java.lang.Character.MODIFIER_SYMBOL;
|
|
||||||
public static final byte OTHER_SYMBOL = java.lang.Character.OTHER_SYMBOL;
|
|
||||||
public static final byte INITIAL_QUOTE_PUNCTUATION = java.lang.Character.INITIAL_QUOTE_PUNCTUATION;
|
|
||||||
public static final byte FINAL_QUOTE_PUNCTUATION = java.lang.Character.FINAL_QUOTE_PUNCTUATION;
|
|
||||||
public static final byte DIRECTIONALITY_UNDEFINED = java.lang.Character.DIRECTIONALITY_UNDEFINED;
|
|
||||||
public static final byte DIRECTIONALITY_LEFT_TO_RIGHT = java.lang.Character.DIRECTIONALITY_LEFT_TO_RIGHT;
|
|
||||||
public static final byte DIRECTIONALITY_RIGHT_TO_LEFT = java.lang.Character.DIRECTIONALITY_RIGHT_TO_LEFT;
|
|
||||||
public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = java.lang.Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
|
|
||||||
public static final byte DIRECTIONALITY_EUROPEAN_NUMBER = java.lang.Character.DIRECTIONALITY_EUROPEAN_NUMBER;
|
|
||||||
public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = java.lang.Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR;
|
|
||||||
public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = java.lang.Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR;
|
|
||||||
public static final byte DIRECTIONALITY_ARABIC_NUMBER = java.lang.Character.DIRECTIONALITY_ARABIC_NUMBER;
|
|
||||||
public static final byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = java.lang.Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR;
|
|
||||||
public static final byte DIRECTIONALITY_NONSPACING_MARK = java.lang.Character.DIRECTIONALITY_NONSPACING_MARK;
|
|
||||||
public static final byte DIRECTIONALITY_BOUNDARY_NEUTRAL = java.lang.Character.DIRECTIONALITY_BOUNDARY_NEUTRAL;
|
|
||||||
public static final byte DIRECTIONALITY_PARAGRAPH_SEPARATOR = java.lang.Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR;
|
|
||||||
public static final byte DIRECTIONALITY_SEGMENT_SEPARATOR = java.lang.Character.DIRECTIONALITY_SEGMENT_SEPARATOR;
|
|
||||||
public static final byte DIRECTIONALITY_WHITESPACE = java.lang.Character.DIRECTIONALITY_WHITESPACE;
|
|
||||||
public static final byte DIRECTIONALITY_OTHER_NEUTRALS = java.lang.Character.DIRECTIONALITY_OTHER_NEUTRALS;
|
|
||||||
public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = java.lang.Character.DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING;
|
|
||||||
public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = java.lang.Character.DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE;
|
|
||||||
public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = java.lang.Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING;
|
|
||||||
public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = java.lang.Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE;
|
|
||||||
public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = java.lang.Character.DIRECTIONALITY_POP_DIRECTIONAL_FORMAT;
|
|
||||||
public static final char MIN_HIGH_SURROGATE = java.lang.Character.MIN_HIGH_SURROGATE;
|
|
||||||
public static final char MAX_HIGH_SURROGATE = java.lang.Character.MAX_HIGH_SURROGATE;
|
|
||||||
public static final char MIN_LOW_SURROGATE = java.lang.Character.MIN_LOW_SURROGATE;
|
|
||||||
public static final char MAX_LOW_SURROGATE = java.lang.Character.MAX_LOW_SURROGATE;
|
|
||||||
public static final char MIN_SURROGATE = java.lang.Character.MIN_SURROGATE;
|
|
||||||
public static final char MAX_SURROGATE = java.lang.Character.MAX_SURROGATE;
|
|
||||||
public static final int MIN_SUPPLEMENTARY_CODE_POINT = java.lang.Character.MIN_SUPPLEMENTARY_CODE_POINT;
|
|
||||||
public static final int MIN_CODE_POINT = java.lang.Character.MIN_CODE_POINT;
|
|
||||||
public static final int MAX_CODE_POINT = java.lang.Character.MAX_CODE_POINT;
|
|
||||||
public static final int BYTES = java.lang.Character.BYTES;
|
|
||||||
public static final int SIZE = java.lang.Character.SIZE;
|
|
||||||
|
|
||||||
private final char value;
|
|
||||||
|
|
||||||
public Character(char c) {
|
|
||||||
this.value = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
public char charValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return hashCode(this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int hashCode(char value) {
|
|
||||||
return java.lang.Character.hashCode(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(java.lang.Object other) {
|
|
||||||
return (other instanceof Character) && ((Character) other).value == value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public java.lang.String toString() {
|
|
||||||
return java.lang.Character.toString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public String toDJVMString() {
|
|
||||||
return toString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
java.lang.Character fromDJVM() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NotNull Character var1) {
|
|
||||||
return compare(this.value, var1.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int compare(char x, char y) {
|
|
||||||
return java.lang.Character.compare(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toString(char c) {
|
|
||||||
return String.toDJVM(java.lang.Character.toString(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Character valueOf(char c) {
|
|
||||||
return (c <= 127) ? Cache.cache[(int)c] : new Character(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isValidCodePoint(int codePoint) {
|
|
||||||
return java.lang.Character.isValidCodePoint(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isBmpCodePoint(int codePoint) {
|
|
||||||
return java.lang.Character.isBmpCodePoint(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSupplementaryCodePoint(int codePoint) {
|
|
||||||
return java.lang.Character.isSupplementaryCodePoint(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isHighSurrogate(char ch) {
|
|
||||||
return java.lang.Character.isHighSurrogate(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isLowSurrogate(char ch) {
|
|
||||||
return java.lang.Character.isLowSurrogate(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSurrogate(char ch) {
|
|
||||||
return java.lang.Character.isSurrogate(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSurrogatePair(char high, char low) {
|
|
||||||
return java.lang.Character.isSurrogatePair(high, low);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int charCount(int codePoint) {
|
|
||||||
return java.lang.Character.charCount(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int toCodePoint(char high, char low) {
|
|
||||||
return java.lang.Character.toCodePoint(high, low);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int codePointAt(CharSequence seq, int index) {
|
|
||||||
return java.lang.Character.codePointAt(seq, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int codePointAt(char[] a, int index) {
|
|
||||||
return java.lang.Character.codePointAt(a, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int codePointAt(char[] a, int index, int limit) {
|
|
||||||
return java.lang.Character.codePointAt(a, index, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int codePointBefore(CharSequence seq, int index) {
|
|
||||||
return java.lang.Character.codePointBefore(seq, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int codePointBefore(char[] a, int index) {
|
|
||||||
return java.lang.Character.codePointBefore(a, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int codePointBefore(char[] a, int index, int limit) {
|
|
||||||
return java.lang.Character.codePointBefore(a, index, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static char highSurrogate(int codePoint) {
|
|
||||||
return java.lang.Character.highSurrogate(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static char lowSurrogate(int codePoint) {
|
|
||||||
return java.lang.Character.lowSurrogate(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int toChars(int codePoint, char[] dst, int dstIndex) {
|
|
||||||
return java.lang.Character.toChars(codePoint, dst, dstIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static char[] toChars(int codePoint) {
|
|
||||||
return java.lang.Character.toChars(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int codePointCount(CharSequence seq, int beginIndex, int endIndex) {
|
|
||||||
return java.lang.Character.codePointCount(seq, beginIndex, endIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int codePointCount(char[] a, int offset, int count) {
|
|
||||||
return java.lang.Character.codePointCount(a, offset, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int offsetByCodePoints(CharSequence seq, int index, int codePointOffset) {
|
|
||||||
return java.lang.Character.offsetByCodePoints(seq, index, codePointOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int offsetByCodePoints(char[] a, int start, int count, int index, int codePointOffset) {
|
|
||||||
return java.lang.Character.offsetByCodePoints(a, start, count, index, codePointOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isLowerCase(char ch) {
|
|
||||||
return java.lang.Character.isLowerCase(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isLowerCase(int codePoint) {
|
|
||||||
return java.lang.Character.isLowerCase(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isUpperCase(char ch) {
|
|
||||||
return java.lang.Character.isUpperCase(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isUpperCase(int codePoint) {
|
|
||||||
return java.lang.Character.isUpperCase(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isTitleCase(char ch) {
|
|
||||||
return java.lang.Character.isTitleCase(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isTitleCase(int codePoint) {
|
|
||||||
return java.lang.Character.isTitleCase(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isDigit(char ch) {
|
|
||||||
return java.lang.Character.isDigit(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isDigit(int codePoint) {
|
|
||||||
return java.lang.Character.isDigit(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isDefined(char ch) {
|
|
||||||
return java.lang.Character.isDefined(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isDefined(int codePoint) {
|
|
||||||
return java.lang.Character.isDefined(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isLetter(char ch) {
|
|
||||||
return java.lang.Character.isLetter(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isLetter(int codePoint) {
|
|
||||||
return java.lang.Character.isLetter(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isLetterOrDigit(char ch) {
|
|
||||||
return java.lang.Character.isLetterOrDigit(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isLetterOrDigit(int codePoint) {
|
|
||||||
return java.lang.Character.isLetterOrDigit(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static boolean isJavaLetter(char ch) {
|
|
||||||
return java.lang.Character.isJavaLetter(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static boolean isJavaLetterOrDigit(char ch) {
|
|
||||||
return java.lang.Character.isJavaLetterOrDigit(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isAlphabetic(int codePoint) {
|
|
||||||
return java.lang.Character.isAlphabetic(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isIdeographic(int codePoint) {
|
|
||||||
return java.lang.Character.isIdeographic(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isJavaIdentifierStart(char ch) {
|
|
||||||
return java.lang.Character.isJavaIdentifierStart(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isJavaIdentifierStart(int codePoint) {
|
|
||||||
return java.lang.Character.isJavaIdentifierStart(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isJavaIdentifierPart(char ch) {
|
|
||||||
return java.lang.Character.isJavaIdentifierPart(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isJavaIdentifierPart(int codePoint) {
|
|
||||||
return java.lang.Character.isJavaIdentifierPart(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isUnicodeIdentifierStart(char ch) {
|
|
||||||
return java.lang.Character.isUnicodeIdentifierStart(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isUnicodeIdentifierStart(int codePoint) {
|
|
||||||
return java.lang.Character.isUnicodeIdentifierStart(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isUnicodeIdentifierPart(char ch) {
|
|
||||||
return java.lang.Character.isUnicodeIdentifierPart(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isUnicodeIdentifierPart(int codePoint) {
|
|
||||||
return java.lang.Character.isUnicodeIdentifierPart(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isIdentifierIgnorable(char ch) {
|
|
||||||
return java.lang.Character.isIdentifierIgnorable(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isIdentifierIgnorable(int codePoint) {
|
|
||||||
return java.lang.Character.isIdentifierIgnorable(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static char toLowerCase(char ch) {
|
|
||||||
return java.lang.Character.toLowerCase(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int toLowerCase(int codePoint) {
|
|
||||||
return java.lang.Character.toLowerCase(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static char toUpperCase(char ch) {
|
|
||||||
return java.lang.Character.toUpperCase(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int toUpperCase(int codePoint) {
|
|
||||||
return java.lang.Character.toUpperCase(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static char toTitleCase(char ch) {
|
|
||||||
return java.lang.Character.toTitleCase(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int toTitleCase(int codePoint) {
|
|
||||||
return java.lang.Character.toTitleCase(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int digit(char ch, int radix) {
|
|
||||||
return java.lang.Character.digit(ch, radix);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int digit(int codePoint, int radix) {
|
|
||||||
return java.lang.Character.digit(codePoint, radix);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getNumericValue(char ch) {
|
|
||||||
return java.lang.Character.getNumericValue(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getNumericValue(int codePoint) {
|
|
||||||
return java.lang.Character.getNumericValue(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static boolean isSpace(char ch) {
|
|
||||||
return java.lang.Character.isSpace(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSpaceChar(char ch) {
|
|
||||||
return java.lang.Character.isSpaceChar(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSpaceChar(int codePoint) {
|
|
||||||
return java.lang.Character.isSpaceChar(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isWhitespace(char ch) {
|
|
||||||
return java.lang.Character.isWhitespace(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isWhitespace(int codePoint) {
|
|
||||||
return java.lang.Character.isWhitespace(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isISOControl(char ch) {
|
|
||||||
return java.lang.Character.isISOControl(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isISOControl(int codePoint) {
|
|
||||||
return java.lang.Character.isISOControl(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getType(char ch) {
|
|
||||||
return java.lang.Character.getType(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getType(int codePoint) {
|
|
||||||
return java.lang.Character.getType(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static char forDigit(int digit, int radix) {
|
|
||||||
return java.lang.Character.forDigit(digit, radix);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte getDirectionality(char ch) {
|
|
||||||
return java.lang.Character.getDirectionality(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte getDirectionality(int codePoint) {
|
|
||||||
return java.lang.Character.getDirectionality(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isMirrored(char ch) {
|
|
||||||
return java.lang.Character.isMirrored(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isMirrored(int codePoint) {
|
|
||||||
return java.lang.Character.isMirrored(codePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getName(int codePoint) {
|
|
||||||
return String.toDJVM(java.lang.Character.getName(codePoint));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Character toDJVM(java.lang.Character c) {
|
|
||||||
return (c == null) ? null : valueOf(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// These three nested classes are placeholders to ensure that
|
|
||||||
// the Character class bytecode is generated correctly. The
|
|
||||||
// real classes will be loaded from the from the bootstrap jar
|
|
||||||
// and then mapped into the sandbox.* namespace.
|
|
||||||
public static final class UnicodeScript extends Enum<UnicodeScript> {
|
|
||||||
private UnicodeScript(String name, int index) {
|
|
||||||
super(name, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NotNull UnicodeScript other) {
|
|
||||||
throw new UnsupportedOperationException("Bootstrap implementation");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static final class UnicodeBlock extends Subset {}
|
|
||||||
public static class Subset extends Object {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Keep pre-allocated instances of the first 128 characters
|
|
||||||
* on the basis that these will be used most frequently.
|
|
||||||
*/
|
|
||||||
private static class Cache {
|
|
||||||
private static final Character[] cache = new Character[128];
|
|
||||||
|
|
||||||
static {
|
|
||||||
for (int c = 0; c < cache.length; ++c) {
|
|
||||||
cache[c] = new Character((char) c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Cache() {}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class that implements just enough of {@link java.lang.Comparable}
|
|
||||||
* to allow us to compile {@link sandbox.java.lang.String}.
|
|
||||||
*/
|
|
||||||
public interface Comparable<T> extends java.lang.Comparable<T> {
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pinned exceptions inherit from {@link java.lang.Throwable}, but we
|
|
||||||
* still need to be able to pass them through the sandbox's
|
|
||||||
* exception handlers. In which case we will wrap them inside
|
|
||||||
* one of these.
|
|
||||||
*
|
|
||||||
* Exceptions wrapped inside one of these cannot be caught.
|
|
||||||
*
|
|
||||||
* Also used for passing exceptions through finally blocks without
|
|
||||||
* any expensive unwrapping to {@link sandbox.java.lang.Throwable}
|
|
||||||
* based types.
|
|
||||||
*/
|
|
||||||
final class DJVMThrowableWrapper extends Throwable {
|
|
||||||
private final java.lang.Throwable throwable;
|
|
||||||
|
|
||||||
DJVMThrowableWrapper(java.lang.Throwable t) {
|
|
||||||
throwable = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevent this wrapper from creating its own stack trace.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final Throwable fillInStackTrace() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
final java.lang.Throwable fromDJVM() {
|
|
||||||
return throwable;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,163 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
||||||
public final class Double extends Number implements Comparable<Double> {
|
|
||||||
public static final double POSITIVE_INFINITY = java.lang.Double.POSITIVE_INFINITY;
|
|
||||||
public static final double NEGATIVE_INFINITY = java.lang.Double.NEGATIVE_INFINITY;
|
|
||||||
public static final double NaN = java.lang.Double.NaN;
|
|
||||||
public static final double MAX_VALUE = java.lang.Double.MAX_VALUE;
|
|
||||||
public static final double MIN_NORMAL = java.lang.Double.MIN_NORMAL;
|
|
||||||
public static final double MIN_VALUE = java.lang.Double.MIN_VALUE;
|
|
||||||
public static final int MAX_EXPONENT = java.lang.Double.MAX_EXPONENT;
|
|
||||||
public static final int MIN_EXPONENT = java.lang.Double.MIN_EXPONENT;
|
|
||||||
public static final int BYTES = java.lang.Double.BYTES;
|
|
||||||
public static final int SIZE = java.lang.Double.SIZE;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static final Class<Double> TYPE = (Class) java.lang.Double.TYPE;
|
|
||||||
|
|
||||||
private final double value;
|
|
||||||
|
|
||||||
public Double(double value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Double(String s) throws NumberFormatException {
|
|
||||||
this.value = parseDouble(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double doubleValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float floatValue() {
|
|
||||||
return (float)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long longValue() {
|
|
||||||
return (long)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int intValue() {
|
|
||||||
return (int)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short shortValue() {
|
|
||||||
return (short)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte byteValue() {
|
|
||||||
return (byte)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNaN() {
|
|
||||||
return java.lang.Double.isNaN(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInfinite() {
|
|
||||||
return isInfinite(this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(java.lang.Object other) {
|
|
||||||
return (other instanceof Double) && doubleToLongBits(((Double)other).value) == doubleToLongBits(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return hashCode(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int hashCode(double d) {
|
|
||||||
return java.lang.Double.hashCode(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public java.lang.String toString() {
|
|
||||||
return java.lang.Double.toString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
java.lang.Double fromDJVM() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NotNull Double other) {
|
|
||||||
return compare(this.value, other.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toString(double d) {
|
|
||||||
return String.toDJVM(java.lang.Double.toString(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toHexString(double d) {
|
|
||||||
return String.toDJVM(java.lang.Double.toHexString(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Double valueOf(String s) throws NumberFormatException {
|
|
||||||
return toDJVM(java.lang.Double.valueOf(String.fromDJVM(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Double valueOf(double d) {
|
|
||||||
return new Double(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double parseDouble(String s) throws NumberFormatException {
|
|
||||||
return java.lang.Double.parseDouble(String.fromDJVM(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isNaN(double d) {
|
|
||||||
return java.lang.Double.isNaN(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isInfinite(double d) {
|
|
||||||
return java.lang.Double.isInfinite(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isFinite(double d) {
|
|
||||||
return java.lang.Double.isFinite(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long doubleToLongBits(double d) {
|
|
||||||
return java.lang.Double.doubleToLongBits(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long doubleToRawLongBits(double d) {
|
|
||||||
return java.lang.Double.doubleToRawLongBits(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double longBitsToDouble(long bits) {
|
|
||||||
return java.lang.Double.longBitsToDouble(bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int compare(double d1, double d2) {
|
|
||||||
return java.lang.Double.compare(d1, d2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double sum(double a, double b) {
|
|
||||||
return java.lang.Double.sum(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double max(double a, double b) {
|
|
||||||
return java.lang.Double.max(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double min(double a, double b) {
|
|
||||||
return java.lang.Double.min(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Double toDJVM(java.lang.Double d) {
|
|
||||||
return (d == null) ? null : valueOf(d);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class. We will load the actual Enum class at run-time.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
||||||
public abstract class Enum<E extends Enum<E>> extends Object implements Comparable<E>, Serializable {
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private final int ordinal;
|
|
||||||
|
|
||||||
protected Enum(String name, int ordinal) {
|
|
||||||
this.name = name;
|
|
||||||
this.ordinal = ordinal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String name() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int ordinal() {
|
|
||||||
return ordinal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
final java.lang.Enum<?> fromDJVM() {
|
|
||||||
throw new UnsupportedOperationException("Dummy implementation");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,163 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
||||||
public final class Float extends Number implements Comparable<Float> {
|
|
||||||
public static final float POSITIVE_INFINITY = java.lang.Float.POSITIVE_INFINITY;
|
|
||||||
public static final float NEGATIVE_INFINITY = java.lang.Float.NEGATIVE_INFINITY;
|
|
||||||
public static final float NaN = java.lang.Float.NaN;
|
|
||||||
public static final float MAX_VALUE = java.lang.Float.MAX_VALUE;
|
|
||||||
public static final float MIN_NORMAL = java.lang.Float.MIN_NORMAL;
|
|
||||||
public static final float MIN_VALUE = java.lang.Float.MIN_VALUE;
|
|
||||||
public static final int MAX_EXPONENT = java.lang.Float.MAX_EXPONENT;
|
|
||||||
public static final int MIN_EXPONENT = java.lang.Float.MIN_EXPONENT;
|
|
||||||
public static final int BYTES = java.lang.Float.BYTES;
|
|
||||||
public static final int SIZE = java.lang.Float.SIZE;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static final Class<Float> TYPE = (Class) java.lang.Float.TYPE;
|
|
||||||
|
|
||||||
private final float value;
|
|
||||||
|
|
||||||
public Float(float value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Float(String s) throws NumberFormatException {
|
|
||||||
this.value = parseFloat(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return hashCode(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int hashCode(float f) {
|
|
||||||
return java.lang.Float.hashCode(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(java.lang.Object other) {
|
|
||||||
return other instanceof Float && floatToIntBits(((Float)other).value) == floatToIntBits(this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public java.lang.String toString() {
|
|
||||||
return java.lang.Float.toString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
java.lang.Float fromDJVM() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double doubleValue() {
|
|
||||||
return (double)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float floatValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long longValue() {
|
|
||||||
return (long)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int intValue() {
|
|
||||||
return (int)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short shortValue() {
|
|
||||||
return (short)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte byteValue() {
|
|
||||||
return (byte)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NotNull Float other) {
|
|
||||||
return compare(this.value, other.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNaN() {
|
|
||||||
return isNaN(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInfinite() {
|
|
||||||
return isInfinite(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toString(float f) {
|
|
||||||
return String.valueOf(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toHexString(float f) {
|
|
||||||
return String.toDJVM(java.lang.Float.toHexString(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Float valueOf(String s) throws NumberFormatException {
|
|
||||||
return toDJVM(java.lang.Float.valueOf(String.fromDJVM(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Float valueOf(float f) {
|
|
||||||
return new Float(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float parseFloat(String s) throws NumberFormatException {
|
|
||||||
return java.lang.Float.parseFloat(String.fromDJVM(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isNaN(float f) {
|
|
||||||
return java.lang.Float.isNaN(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isInfinite(float f) {
|
|
||||||
return java.lang.Float.isInfinite(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isFinite(float f) {
|
|
||||||
return java.lang.Float.isFinite(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int floatToIntBits(float f) {
|
|
||||||
return java.lang.Float.floatToIntBits(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int floatToRawIntBits(float f) {
|
|
||||||
return java.lang.Float.floatToIntBits(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float intBitsToFloat(int bits) {
|
|
||||||
return java.lang.Float.intBitsToFloat(bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int compare(float f1, float f2) {
|
|
||||||
return java.lang.Float.compare(f1, f2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float sum(float a, float b) {
|
|
||||||
return java.lang.Float.sum(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float max(float a, float b) {
|
|
||||||
return java.lang.Float.max(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float min(float a, float b) {
|
|
||||||
return java.lang.Float.min(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Float toDJVM(java.lang.Float f) {
|
|
||||||
return (f == null) ? null : valueOf(f);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,241 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
||||||
public final class Integer extends Number implements Comparable<Integer> {
|
|
||||||
|
|
||||||
public static final int MIN_VALUE = java.lang.Integer.MIN_VALUE;
|
|
||||||
public static final int MAX_VALUE = java.lang.Integer.MAX_VALUE;
|
|
||||||
public static final int BYTES = java.lang.Integer.BYTES;
|
|
||||||
public static final int SIZE = java.lang.Integer.SIZE;
|
|
||||||
|
|
||||||
static final int[] SIZE_TABLE = new int[] { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, MAX_VALUE };
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static final Class<Integer> TYPE = (Class) java.lang.Integer.TYPE;
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
public Integer(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer(String s) throws NumberFormatException {
|
|
||||||
this.value = parseInt(s, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Integer.hashCode(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int hashCode(int i) {
|
|
||||||
return java.lang.Integer.hashCode(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(java.lang.Object other) {
|
|
||||||
return (other instanceof Integer) && (value == ((Integer) other).value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int intValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long longValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short shortValue() {
|
|
||||||
return (short) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte byteValue() {
|
|
||||||
return (byte) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float floatValue() {
|
|
||||||
return (float) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double doubleValue() {
|
|
||||||
return (double) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NotNull Integer other) {
|
|
||||||
return compare(this.value, other.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public java.lang.String toString() {
|
|
||||||
return java.lang.Integer.toString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
java.lang.Integer fromDJVM() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toString(int i, int radix) {
|
|
||||||
return String.toDJVM(java.lang.Integer.toString(i, radix));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toUnsignedString(int i, int radix) {
|
|
||||||
return String.toDJVM(java.lang.Integer.toUnsignedString(i, radix));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toHexString(int i) {
|
|
||||||
return String.toDJVM(java.lang.Integer.toHexString(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toOctalString(int i) {
|
|
||||||
return String.toDJVM(java.lang.Integer.toOctalString(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toBinaryString(int i) {
|
|
||||||
return String.toDJVM(java.lang.Integer.toBinaryString(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toString(int i) {
|
|
||||||
return String.toDJVM(java.lang.Integer.toString(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toUnsignedString(int i) {
|
|
||||||
return String.toDJVM(java.lang.Integer.toUnsignedString(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int parseInt(String s, int radix) throws NumberFormatException {
|
|
||||||
return java.lang.Integer.parseInt(String.fromDJVM(s), radix);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int parseInt(String s) throws NumberFormatException {
|
|
||||||
return java.lang.Integer.parseInt(String.fromDJVM(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int parseUnsignedInt(String s, int radix) throws NumberFormatException {
|
|
||||||
return java.lang.Integer.parseUnsignedInt(String.fromDJVM(s), radix);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int parseUnsignedInt(String s) throws NumberFormatException {
|
|
||||||
return java.lang.Integer.parseUnsignedInt(String.fromDJVM(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Integer valueOf(String s, int radix) throws NumberFormatException {
|
|
||||||
return toDJVM(java.lang.Integer.valueOf(String.fromDJVM(s), radix));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Integer valueOf(String s) throws NumberFormatException {
|
|
||||||
return toDJVM(java.lang.Integer.valueOf(String.fromDJVM(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Integer valueOf(int i) {
|
|
||||||
return new Integer(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Integer decode(String nm) throws NumberFormatException {
|
|
||||||
return new Integer(java.lang.Integer.decode(String.fromDJVM(nm)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int compare(int x, int y) {
|
|
||||||
return java.lang.Integer.compare(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int compareUnsigned(int x, int y) {
|
|
||||||
return java.lang.Integer.compareUnsigned(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long toUnsignedLong(int x) {
|
|
||||||
return java.lang.Integer.toUnsignedLong(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int divideUnsigned(int dividend, int divisor) {
|
|
||||||
return java.lang.Integer.divideUnsigned(dividend, divisor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int remainderUnsigned(int dividend, int divisor) {
|
|
||||||
return java.lang.Integer.remainderUnsigned(dividend, divisor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int highestOneBit(int i) {
|
|
||||||
return java.lang.Integer.highestOneBit(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int lowestOneBit(int i) {
|
|
||||||
return java.lang.Integer.lowestOneBit(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int numberOfLeadingZeros(int i) {
|
|
||||||
return java.lang.Integer.numberOfLeadingZeros(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int numberOfTrailingZeros(int i) {
|
|
||||||
return java.lang.Integer.numberOfTrailingZeros(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int bitCount(int i) {
|
|
||||||
return java.lang.Integer.bitCount(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int rotateLeft(int i, int distance) {
|
|
||||||
return java.lang.Integer.rotateLeft(i, distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int rotateRight(int i, int distance) {
|
|
||||||
return java.lang.Integer.rotateRight(i, distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int reverse(int i) {
|
|
||||||
return java.lang.Integer.reverse(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int signum(int i) {
|
|
||||||
return java.lang.Integer.signum(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int reverseBytes(int i) {
|
|
||||||
return java.lang.Integer.reverseBytes(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int sum(int a, int b) {
|
|
||||||
return java.lang.Integer.sum(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int max(int a, int b) {
|
|
||||||
return java.lang.Integer.max(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int min(int a, int b) {
|
|
||||||
return java.lang.Integer.min(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Integer toDJVM(java.lang.Integer i) {
|
|
||||||
return (i == null) ? null : valueOf(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stringSize(final int number) {
|
|
||||||
int i = 0;
|
|
||||||
while (number > SIZE_TABLE[i]) {
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
return i + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getChars(final int number, int index, char[] buffer) {
|
|
||||||
java.lang.String s = java.lang.Integer.toString(number);
|
|
||||||
int length = s.length();
|
|
||||||
|
|
||||||
while (length > 0) {
|
|
||||||
buffer[--index] = s.charAt(--length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class that implements just enough of {@link java.lang.Iterable}
|
|
||||||
* to allow us to compile {@link sandbox.java.lang.String}.
|
|
||||||
*/
|
|
||||||
public interface Iterable<T> extends java.lang.Iterable<T> {
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
Iterator<T> iterator();
|
|
||||||
}
|
|
@ -1,239 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
||||||
public final class Long extends Number implements Comparable<Long> {
|
|
||||||
|
|
||||||
public static final long MIN_VALUE = java.lang.Long.MIN_VALUE;
|
|
||||||
public static final long MAX_VALUE = java.lang.Long.MAX_VALUE;
|
|
||||||
public static final int BYTES = java.lang.Long.BYTES;
|
|
||||||
public static final int SIZE = java.lang.Long.SIZE;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static final Class<Long> TYPE = (Class) java.lang.Long.TYPE;
|
|
||||||
|
|
||||||
private final long value;
|
|
||||||
|
|
||||||
public Long(long value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long(String s) throws NumberFormatException {
|
|
||||||
this.value = parseLong(s, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return hashCode(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(java.lang.Object other) {
|
|
||||||
return (other instanceof Long) && ((Long) other).longValue() == value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int hashCode(long l) {
|
|
||||||
return java.lang.Long.hashCode(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int intValue() {
|
|
||||||
return (int) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long longValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short shortValue() {
|
|
||||||
return (short) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte byteValue() {
|
|
||||||
return (byte) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float floatValue() {
|
|
||||||
return (float) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double doubleValue() {
|
|
||||||
return (double) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NotNull Long other) {
|
|
||||||
return compare(value, other.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int compare(long x, long y) {
|
|
||||||
return java.lang.Long.compare(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
java.lang.Long fromDJVM() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public java.lang.String toString() {
|
|
||||||
return java.lang.Long.toString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toString(long l) {
|
|
||||||
return String.toDJVM(java.lang.Long.toString(l));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toString(long l, int radix) {
|
|
||||||
return String.toDJVM(java.lang.Long.toString(l, radix));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toUnsignedString(long l, int radix) {
|
|
||||||
return String.toDJVM(java.lang.Long.toUnsignedString(l, radix));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toUnsignedString(long l) {
|
|
||||||
return String.toDJVM(java.lang.Long.toUnsignedString(l));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toHexString(long l) {
|
|
||||||
return String.toDJVM(java.lang.Long.toHexString(l));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toOctalString(long l) {
|
|
||||||
return String.toDJVM(java.lang.Long.toOctalString(l));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toBinaryString(long l) {
|
|
||||||
return String.toDJVM(java.lang.Long.toBinaryString(l));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long parseLong(String s, int radix) throws NumberFormatException {
|
|
||||||
return java.lang.Long.parseLong(String.fromDJVM(s), radix);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long parseLong(String s) throws NumberFormatException {
|
|
||||||
return java.lang.Long.parseLong(String.fromDJVM(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long parseUnsignedLong(String s, int radix) throws NumberFormatException {
|
|
||||||
return java.lang.Long.parseUnsignedLong(String.fromDJVM(s), radix);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long parseUnsignedLong(String s) throws NumberFormatException {
|
|
||||||
return java.lang.Long.parseUnsignedLong(String.fromDJVM(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Long valueOf(String s, int radix) throws NumberFormatException {
|
|
||||||
return toDJVM(java.lang.Long.valueOf(String.fromDJVM(s), radix));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Long valueOf(String s) throws NumberFormatException {
|
|
||||||
return toDJVM(java.lang.Long.valueOf(String.fromDJVM(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Long valueOf(long l) {
|
|
||||||
return new Long(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Long decode(String s) throws NumberFormatException {
|
|
||||||
return toDJVM(java.lang.Long.decode(String.fromDJVM(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int compareUnsigned(long x, long y) {
|
|
||||||
return java.lang.Long.compareUnsigned(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long divideUnsigned(long dividend, long divisor) {
|
|
||||||
return java.lang.Long.divideUnsigned(dividend, divisor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long remainderUnsigned(long dividend, long divisor) {
|
|
||||||
return java.lang.Long.remainderUnsigned(dividend, divisor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long highestOneBit(long l) {
|
|
||||||
return java.lang.Long.highestOneBit(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long lowestOneBit(long l) {
|
|
||||||
return java.lang.Long.lowestOneBit(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int numberOfLeadingZeros(long l) {
|
|
||||||
return java.lang.Long.numberOfLeadingZeros(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int numberOfTrailingZeros(long l) {
|
|
||||||
return java.lang.Long.numberOfTrailingZeros(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int bitCount(long l) {
|
|
||||||
return java.lang.Long.bitCount(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long rotateLeft(long i, int distance) {
|
|
||||||
return java.lang.Long.rotateLeft(i, distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long rotateRight(long i, int distance) {
|
|
||||||
return java.lang.Long.rotateRight(i, distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long reverse(long l) {
|
|
||||||
return java.lang.Long.reverse(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int signum(long l) {
|
|
||||||
return java.lang.Long.signum(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long reverseBytes(long l) {
|
|
||||||
return java.lang.Long.reverseBytes(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long sum(long a, long b) {
|
|
||||||
return java.lang.Long.sum(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long max(long a, long b) {
|
|
||||||
return java.lang.Long.max(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long min(long a, long b) {
|
|
||||||
return java.lang.Long.min(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Long toDJVM(java.lang.Long l) {
|
|
||||||
return (l == null) ? null : valueOf(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stringSize(final long number) {
|
|
||||||
long l = 10;
|
|
||||||
int i = 1;
|
|
||||||
|
|
||||||
while ((i < 19) && (number >= l)) {
|
|
||||||
l *= 10;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getChars(final long number, int index, char[] buffer) {
|
|
||||||
java.lang.String s = java.lang.Long.toString(number);
|
|
||||||
int length = s.length();
|
|
||||||
|
|
||||||
while (length > 0) {
|
|
||||||
buffer[--index] = s.charAt(--length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public abstract class Number extends Object implements Serializable {
|
|
||||||
|
|
||||||
public abstract double doubleValue();
|
|
||||||
public abstract float floatValue();
|
|
||||||
public abstract long longValue();
|
|
||||||
public abstract int intValue();
|
|
||||||
public abstract short shortValue();
|
|
||||||
public abstract byte byteValue();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public String toDJVMString() {
|
|
||||||
return String.toDJVM(toString());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import sandbox.net.corda.djvm.rules.RuleViolationError;
|
|
||||||
|
|
||||||
public class Object {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return sandbox.java.lang.System.identityHashCode(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public java.lang.String toString() {
|
|
||||||
return toDJVMString().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public String toDJVMString() {
|
|
||||||
return String.toDJVM("sandbox.java.lang.Object@" + java.lang.Integer.toString(hashCode(), 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
java.lang.Object fromDJVM() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static java.lang.Object[] fromDJVM(java.lang.Object[] args) {
|
|
||||||
if (args == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
java.lang.Object[] unwrapped = (java.lang.Object[]) java.lang.reflect.Array.newInstance(
|
|
||||||
fromDJVM(args.getClass().getComponentType()), args.length
|
|
||||||
);
|
|
||||||
int i = 0;
|
|
||||||
for (java.lang.Object arg : args) {
|
|
||||||
unwrapped[i] = unwrap(arg);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
return unwrapped;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static java.lang.Object unwrap(java.lang.Object arg) {
|
|
||||||
if (arg instanceof Object) {
|
|
||||||
return ((Object) arg).fromDJVM();
|
|
||||||
} else if (java.lang.Object[].class.isAssignableFrom(arg.getClass())) {
|
|
||||||
return fromDJVM((java.lang.Object[]) arg);
|
|
||||||
} else {
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Class<?> fromDJVM(Class<?> type) {
|
|
||||||
try {
|
|
||||||
return DJVM.fromDJVMType(type);
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new RuleViolationError(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static java.util.Locale fromDJVM(sandbox.java.util.Locale locale) {
|
|
||||||
return java.util.Locale.forLanguageTag(locale.toLanguageTag().fromDJVM());
|
|
||||||
}
|
|
||||||
|
|
||||||
static java.nio.charset.Charset fromDJVM(sandbox.java.nio.charset.Charset charset) {
|
|
||||||
return java.nio.charset.Charset.forName(charset.name().fromDJVM());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public final class Runtime extends Object {
|
|
||||||
private static final Runtime RUNTIME = new Runtime();
|
|
||||||
|
|
||||||
private Runtime() {}
|
|
||||||
|
|
||||||
public static Runtime getRuntime() {
|
|
||||||
return RUNTIME;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Everything inside the sandbox is single-threaded.
|
|
||||||
* @return 1
|
|
||||||
*/
|
|
||||||
public int availableProcessors() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadLibrary(String libraryName) {}
|
|
||||||
|
|
||||||
public void load(String fileName) {}
|
|
||||||
|
|
||||||
public void runFinalization() {}
|
|
||||||
public void gc() {}
|
|
||||||
}
|
|
@ -1,128 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
||||||
public final class Short extends Number implements Comparable<Short> {
|
|
||||||
public static final short MIN_VALUE = java.lang.Short.MIN_VALUE;
|
|
||||||
public static final short MAX_VALUE = java.lang.Short.MAX_VALUE;
|
|
||||||
public static final int BYTES = java.lang.Short.BYTES;
|
|
||||||
public static final int SIZE = java.lang.Short.SIZE;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static final Class<Short> TYPE = (Class) java.lang.Short.TYPE;
|
|
||||||
|
|
||||||
private final short value;
|
|
||||||
|
|
||||||
public Short(short value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Short(String s) throws NumberFormatException {
|
|
||||||
this.value = parseShort(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte byteValue() {
|
|
||||||
return (byte)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short shortValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int intValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long longValue() {
|
|
||||||
return (long)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float floatValue() {
|
|
||||||
return (float)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double doubleValue() {
|
|
||||||
return (double)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public java.lang.String toString() {
|
|
||||||
return java.lang.Integer.toString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
java.lang.Short fromDJVM() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return hashCode(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int hashCode(short value) {
|
|
||||||
return java.lang.Short.hashCode(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(java.lang.Object other) {
|
|
||||||
return (other instanceof Short) && ((Short) other).value == value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int compareTo(@NotNull Short other) {
|
|
||||||
return compare(this.value, other.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int compare(short x, short y) {
|
|
||||||
return java.lang.Short.compare(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static short reverseBytes(short value) {
|
|
||||||
return java.lang.Short.reverseBytes(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int toUnsignedInt(short x) {
|
|
||||||
return java.lang.Short.toUnsignedInt(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long toUnsignedLong(short x) {
|
|
||||||
return java.lang.Short.toUnsignedLong(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static short parseShort(String s, int radix) throws NumberFormatException {
|
|
||||||
return java.lang.Short.parseShort(String.fromDJVM(s), radix);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static short parseShort(String s) throws NumberFormatException {
|
|
||||||
return java.lang.Short.parseShort(String.fromDJVM(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Short valueOf(String s, int radix) throws NumberFormatException {
|
|
||||||
return toDJVM(java.lang.Short.valueOf(String.fromDJVM(s), radix));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Short valueOf(String s) throws NumberFormatException {
|
|
||||||
return toDJVM(java.lang.Short.valueOf(String.fromDJVM(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Short valueOf(short s) {
|
|
||||||
return new Short(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Short decode(String nm) throws NumberFormatException {
|
|
||||||
return toDJVM(java.lang.Short.decode(String.fromDJVM(nm)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Short toDJVM(java.lang.Short i) {
|
|
||||||
return (i == null) ? null : valueOf(i);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class. We will load the genuine class at runtime.
|
|
||||||
*/
|
|
||||||
public final class StackTraceElement extends Object implements java.io.Serializable {
|
|
||||||
|
|
||||||
private final String className;
|
|
||||||
private final String methodName;
|
|
||||||
private final String fileName;
|
|
||||||
private final int lineNumber;
|
|
||||||
|
|
||||||
public StackTraceElement(String className, String methodName, String fileName, int lineNumber) {
|
|
||||||
this.className = className;
|
|
||||||
this.methodName = methodName;
|
|
||||||
this.fileName = fileName;
|
|
||||||
this.lineNumber = lineNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClassName() {
|
|
||||||
return className;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMethodName() {
|
|
||||||
return methodName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFileName() {
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLineNumber() {
|
|
||||||
return lineNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public String toDJVMString() {
|
|
||||||
return String.toDJVM(
|
|
||||||
className.toString() + ':' + methodName.toString()
|
|
||||||
+ (fileName != null ? '(' + fileName.toString() + ':' + lineNumber + ')' : "")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,424 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import net.corda.djvm.SandboxRuntimeContext;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import sandbox.java.nio.charset.Charset;
|
|
||||||
import sandbox.java.util.Comparator;
|
|
||||||
import sandbox.java.util.Locale;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public final class String extends Object implements Comparable<String>, CharSequence, Serializable {
|
|
||||||
public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
|
|
||||||
|
|
||||||
private static class CaseInsensitiveComparator extends Object implements Comparator<String>, Serializable {
|
|
||||||
@Override
|
|
||||||
public int compare(String s1, String s2) {
|
|
||||||
return java.lang.String.CASE_INSENSITIVE_ORDER.compare(String.fromDJVM(s1), String.fromDJVM(s2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String TRUE = new String("true");
|
|
||||||
private static final String FALSE = new String("false");
|
|
||||||
|
|
||||||
private static final Constructor SHARED;
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
SHARED = java.lang.String.class.getDeclaredConstructor(char[].class, java.lang.Boolean.TYPE);
|
|
||||||
SHARED.setAccessible(true);
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
throw new NoSuchMethodError(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final java.lang.String value;
|
|
||||||
|
|
||||||
public String() {
|
|
||||||
this.value = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String(java.lang.String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String(char value[]) {
|
|
||||||
this.value = new java.lang.String(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String(char value[], int offset, int count) {
|
|
||||||
this.value = new java.lang.String(value, offset, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String(int[] codePoints, int offset, int count) {
|
|
||||||
this.value = new java.lang.String(codePoints, offset, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public String(byte ascii[], int hibyte, int offset, int count) {
|
|
||||||
this.value = new java.lang.String(ascii, hibyte, offset, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public String(byte ascii[], int hibyte) {
|
|
||||||
this.value = new java.lang.String(ascii, hibyte);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String(byte bytes[], int offset, int length, String charsetName)
|
|
||||||
throws UnsupportedEncodingException {
|
|
||||||
this.value = new java.lang.String(bytes, offset, length, fromDJVM(charsetName));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String(byte bytes[], int offset, int length, Charset charset) {
|
|
||||||
this.value = new java.lang.String(bytes, offset, length, fromDJVM(charset));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String(byte bytes[], String charsetName)
|
|
||||||
throws UnsupportedEncodingException {
|
|
||||||
this.value = new java.lang.String(bytes, fromDJVM(charsetName));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String(byte bytes[], Charset charset) {
|
|
||||||
this.value = new java.lang.String(bytes, fromDJVM(charset));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String(byte bytes[], int offset, int length) {
|
|
||||||
this.value = new java.lang.String(bytes, offset, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String(byte bytes[]) {
|
|
||||||
this.value = new java.lang.String(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String(StringBuffer buffer) {
|
|
||||||
this.value = buffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String(StringBuilder builder) {
|
|
||||||
this.value = builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
String(char[] value, boolean share) {
|
|
||||||
java.lang.String newValue;
|
|
||||||
try {
|
|
||||||
// This is (presumably) an optimisation for memory usage.
|
|
||||||
newValue = (java.lang.String) SHARED.newInstance(value, share);
|
|
||||||
} catch (Exception e) {
|
|
||||||
newValue = new java.lang.String(value);
|
|
||||||
}
|
|
||||||
this.value = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char charAt(int index) {
|
|
||||||
return value.charAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int length() {
|
|
||||||
return value.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return value.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int codePointAt(int index) {
|
|
||||||
return value.codePointAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int codePointBefore(int index) {
|
|
||||||
return value.codePointBefore(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int codePointCount(int beginIndex, int endIndex) {
|
|
||||||
return value.codePointCount(beginIndex, endIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int offsetByCodePoints(int index, int codePointOffset) {
|
|
||||||
return value.offsetByCodePoints(index, codePointOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
|
|
||||||
value.getChars(srcBegin, srcEnd, dst, dstBegin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) {
|
|
||||||
value.getBytes(srcBegin, srcEnd, dst, dstBegin);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {
|
|
||||||
return value.getBytes(fromDJVM(charsetName));
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes(Charset charset) {
|
|
||||||
return value.getBytes(fromDJVM(charset));
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes() {
|
|
||||||
return value.getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(java.lang.Object other) {
|
|
||||||
return (other instanceof String) && ((String) other).value.equals(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return value.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public java.lang.String toString() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public String toDJVMString() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
java.lang.String fromDJVM() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contentEquals(StringBuffer sb) {
|
|
||||||
return value.contentEquals((CharSequence) sb);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contentEquals(CharSequence cs) {
|
|
||||||
return value.contentEquals(cs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equalsIgnoreCase(String anotherString) {
|
|
||||||
return value.equalsIgnoreCase(fromDJVM(anotherString));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence subSequence(int start, int end) {
|
|
||||||
return toDJVM((java.lang.String) value.subSequence(start, end));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NotNull String other) {
|
|
||||||
return value.compareTo(other.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public int compareToIgnoreCase(String str) {
|
|
||||||
return value.compareToIgnoreCase(fromDJVM(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean regionMatches(int toffset, String other, int ooffset, int len) {
|
|
||||||
return value.regionMatches(toffset, fromDJVM(other), ooffset, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean regionMatches(boolean ignoreCase, int toffset,
|
|
||||||
String other, int ooffset, int len) {
|
|
||||||
return value.regionMatches(ignoreCase, toffset, fromDJVM(other), ooffset, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean startsWith(String prefix, int toffset) {
|
|
||||||
return value.startsWith(fromDJVM(prefix), toffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean startsWith(String prefix) {
|
|
||||||
return value.startsWith(fromDJVM(prefix));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean endsWith(String suffix) {
|
|
||||||
return value.endsWith(fromDJVM(suffix));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int indexOf(int ch) {
|
|
||||||
return value.indexOf(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int indexOf(int ch, int fromIndex) {
|
|
||||||
return value.indexOf(ch, fromIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int lastIndexOf(int ch) {
|
|
||||||
return value.lastIndexOf(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int lastIndexOf(int ch, int fromIndex) {
|
|
||||||
return value.lastIndexOf(ch, fromIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int indexOf(String str) {
|
|
||||||
return value.indexOf(fromDJVM(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int indexOf(String str, int fromIndex) {
|
|
||||||
return value.indexOf(fromDJVM(str), fromIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int lastIndexOf(String str) {
|
|
||||||
return value.lastIndexOf(fromDJVM(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int lastIndexOf(String str, int fromIndex) {
|
|
||||||
return value.lastIndexOf(fromDJVM(str), fromIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String substring(int beginIndex) {
|
|
||||||
return toDJVM(value.substring(beginIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String substring(int beginIndex, int endIndex) {
|
|
||||||
return toDJVM(value.substring(beginIndex, endIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String concat(String str) {
|
|
||||||
return toDJVM(value.concat(fromDJVM(str)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String replace(char oldChar, char newChar) {
|
|
||||||
return toDJVM(value.replace(oldChar, newChar));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean matches(String regex) {
|
|
||||||
return value.matches(fromDJVM(regex));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contains(CharSequence s) {
|
|
||||||
return value.contains(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String replaceFirst(String regex, String replacement) {
|
|
||||||
return toDJVM(value.replaceFirst(fromDJVM(regex), fromDJVM(replacement)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String replaceAll(String regex, String replacement) {
|
|
||||||
return toDJVM(value.replaceAll(fromDJVM(regex), fromDJVM(replacement)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String replace(CharSequence target, CharSequence replacement) {
|
|
||||||
return toDJVM(value.replace(target, replacement));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] split(String regex, int limit) {
|
|
||||||
return toDJVM(value.split(fromDJVM(regex), limit));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] split(String regex) {
|
|
||||||
return toDJVM(value.split(fromDJVM(regex)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toLowerCase(Locale locale) {
|
|
||||||
return toDJVM(value.toLowerCase(fromDJVM(locale)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toLowerCase() {
|
|
||||||
return toDJVM(value.toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toUpperCase(Locale locale) {
|
|
||||||
return toDJVM(value.toUpperCase(fromDJVM(locale)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toUpperCase() {
|
|
||||||
return toDJVM(value.toUpperCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String trim() {
|
|
||||||
return toDJVM(value.trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String intern() { return (String) SandboxRuntimeContext.getInstance().intern(value, this); }
|
|
||||||
|
|
||||||
public char[] toCharArray() {
|
|
||||||
return value.toCharArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String format(String format, java.lang.Object... args) {
|
|
||||||
return toDJVM(java.lang.String.format(fromDJVM(format), fromDJVM(args)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String format(Locale locale, String format, java.lang.Object... args) {
|
|
||||||
return toDJVM(java.lang.String.format(fromDJVM(locale), fromDJVM(format), fromDJVM(args)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String join(CharSequence delimiter, CharSequence... elements) {
|
|
||||||
return toDJVM(java.lang.String.join(delimiter, elements));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String join(CharSequence delimiter,
|
|
||||||
Iterable<? extends CharSequence> elements) {
|
|
||||||
return toDJVM(java.lang.String.join(delimiter, elements));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String valueOf(java.lang.Object obj) {
|
|
||||||
return (obj instanceof Object) ? ((Object) obj).toDJVMString() : toDJVM(java.lang.String.valueOf(obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String valueOf(char data[]) {
|
|
||||||
return toDJVM(java.lang.String.valueOf(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String valueOf(char data[], int offset, int count) {
|
|
||||||
return toDJVM(java.lang.String.valueOf(data, offset, count));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String copyValueOf(char data[], int offset, int count) {
|
|
||||||
return toDJVM(java.lang.String.copyValueOf(data, offset, count));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String copyValueOf(char data[]) {
|
|
||||||
return toDJVM(java.lang.String.copyValueOf(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String valueOf(boolean b) {
|
|
||||||
return b ? TRUE : FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String valueOf(char c) {
|
|
||||||
return toDJVM(java.lang.String.valueOf(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String valueOf(int i) {
|
|
||||||
return toDJVM(java.lang.String.valueOf(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String valueOf(long l) {
|
|
||||||
return toDJVM(java.lang.String.valueOf(l));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String valueOf(float f) {
|
|
||||||
return toDJVM(java.lang.String.valueOf(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String valueOf(double d) {
|
|
||||||
return toDJVM(java.lang.String.valueOf(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
static String[] toDJVM(java.lang.String[] value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String[] result = new String[value.length];
|
|
||||||
int i = 0;
|
|
||||||
for (java.lang.String v : value) {
|
|
||||||
result[i] = toDJVM(v);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toDJVM(java.lang.String value) {
|
|
||||||
return (value == null) ? null : new String(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static java.lang.String fromDJVM(String value) {
|
|
||||||
return (value == null) ? null : value.fromDJVM();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class that implements just enough of {@link java.lang.StringBuffer}
|
|
||||||
* to allow us to compile {@link sandbox.java.lang.String}.
|
|
||||||
*/
|
|
||||||
public abstract class StringBuffer extends Object implements CharSequence, Appendable, Serializable {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract StringBuffer append(CharSequence seq);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract StringBuffer append(CharSequence seq, int start, int end);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract StringBuffer append(char c);
|
|
||||||
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class that implements just enough of {@link java.lang.StringBuilder}
|
|
||||||
* to allow us to compile {@link sandbox.java.lang.String}.
|
|
||||||
*/
|
|
||||||
public abstract class StringBuilder extends Object implements Appendable, CharSequence, Serializable {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract StringBuilder append(CharSequence seq);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract StringBuilder append(CharSequence seq, int start, int end);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract StringBuilder append(char c);
|
|
||||||
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import net.corda.djvm.SandboxRuntimeContext;
|
|
||||||
|
|
||||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
|
||||||
public final class System extends Object {
|
|
||||||
|
|
||||||
private System() {}
|
|
||||||
|
|
||||||
public static int identityHashCode(java.lang.Object obj) {
|
|
||||||
int nativeHashCode = java.lang.System.identityHashCode(obj);
|
|
||||||
return SandboxRuntimeContext.getInstance().getHashCodeFor(nativeHashCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String lineSeparator = String.toDJVM("\n");
|
|
||||||
|
|
||||||
public static void arraycopy(java.lang.Object src, int srcPos, java.lang.Object dest, int destPos, int length) {
|
|
||||||
java.lang.System.arraycopy(src, srcPos, dest, destPos, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void runFinalization() {}
|
|
||||||
public static void gc() {}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import sandbox.java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Everything inside the sandbox is single-threaded, so this
|
|
||||||
* implementation of ThreadLocal is sufficient.
|
|
||||||
* @param <T> Underlying type of this thread-local variable.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
||||||
public class ThreadLocal<T> extends Object {
|
|
||||||
|
|
||||||
private T value;
|
|
||||||
private boolean isSet;
|
|
||||||
|
|
||||||
public ThreadLocal() {
|
|
||||||
}
|
|
||||||
|
|
||||||
protected T initialValue() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T get() {
|
|
||||||
if (!isSet) {
|
|
||||||
set(initialValue());
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set(T value) {
|
|
||||||
this.value = value;
|
|
||||||
this.isSet = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove() {
|
|
||||||
value = null;
|
|
||||||
isSet = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <V> ThreadLocal<V> withInitial(Supplier<? extends V> supplier) {
|
|
||||||
return new SuppliedThreadLocal<>(supplier);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stub class for compiling ThreadLocal. The sandbox will import the
|
|
||||||
// actual SuppliedThreadLocal class at run-time. Having said that, we
|
|
||||||
// still need a working implementation here for the sake of our tests.
|
|
||||||
static final class SuppliedThreadLocal<T> extends ThreadLocal<T> {
|
|
||||||
private final Supplier<? extends T> supplier;
|
|
||||||
|
|
||||||
SuppliedThreadLocal(Supplier<? extends T> supplier) {
|
|
||||||
this.supplier = supplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected T initialValue() {
|
|
||||||
return supplier.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,137 +0,0 @@
|
|||||||
package sandbox.java.lang;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import sandbox.TaskTypes;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
||||||
public class Throwable extends Object implements Serializable {
|
|
||||||
private static final StackTraceElement[] NO_STACK_TRACE = new StackTraceElement[0];
|
|
||||||
|
|
||||||
private String message;
|
|
||||||
private Throwable cause;
|
|
||||||
private StackTraceElement[] stackTrace;
|
|
||||||
|
|
||||||
public Throwable() {
|
|
||||||
this.cause = this;
|
|
||||||
fillInStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Throwable(String message) {
|
|
||||||
this();
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Throwable(Throwable cause) {
|
|
||||||
this.cause = cause;
|
|
||||||
this.message = (cause == null) ? null : cause.toDJVMString();
|
|
||||||
fillInStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Throwable(String message, Throwable cause) {
|
|
||||||
this.message = message;
|
|
||||||
this.cause = cause;
|
|
||||||
fillInStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Throwable(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
|
||||||
if (writableStackTrace) {
|
|
||||||
fillInStackTrace();
|
|
||||||
} else {
|
|
||||||
stackTrace = NO_STACK_TRACE;
|
|
||||||
}
|
|
||||||
this.message = message;
|
|
||||||
this.cause = cause;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMessage() {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLocalizedMessage() {
|
|
||||||
return getMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Throwable getCause() {
|
|
||||||
return (cause == this) ? null : cause;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Throwable initCause(Throwable cause) {
|
|
||||||
if (this.cause != this) {
|
|
||||||
throw new java.lang.IllegalStateException(
|
|
||||||
"Can't overwrite cause with " + java.util.Objects.toString(cause, "a null"), fromDJVM());
|
|
||||||
}
|
|
||||||
if (cause == this) {
|
|
||||||
throw new java.lang.IllegalArgumentException("Self-causation not permitted", fromDJVM());
|
|
||||||
}
|
|
||||||
this.cause = cause;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public String toDJVMString() {
|
|
||||||
java.lang.String s = getClass().getName();
|
|
||||||
String localized = getLocalizedMessage();
|
|
||||||
return String.valueOf((localized != null) ? (s + ": " + localized.toString()) : s);
|
|
||||||
}
|
|
||||||
|
|
||||||
public StackTraceElement[] getStackTrace() {
|
|
||||||
return (stackTrace == NO_STACK_TRACE) ? stackTrace : stackTrace.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStackTrace(StackTraceElement[] stackTrace) {
|
|
||||||
StackTraceElement[] traceCopy = stackTrace.clone();
|
|
||||||
|
|
||||||
for (int i = 0; i < traceCopy.length; ++i) {
|
|
||||||
if (traceCopy[i] == null) {
|
|
||||||
throw new java.lang.NullPointerException("stackTrace[" + i + ']');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.stackTrace = traceCopy;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"ThrowableNotThrown", "UnusedReturnValue"})
|
|
||||||
public Throwable fillInStackTrace() {
|
|
||||||
if (stackTrace == null) {
|
|
||||||
/*
|
|
||||||
* We have been invoked from within this exception's constructor.
|
|
||||||
* Work our way up the stack trace until we find this constructor,
|
|
||||||
* and then find out who actually invoked it. This is where our
|
|
||||||
* sandboxed stack trace will start from.
|
|
||||||
*
|
|
||||||
* Our stack trace will end at the point where we entered the sandbox.
|
|
||||||
*/
|
|
||||||
final java.lang.StackTraceElement[] elements = new java.lang.Throwable().getStackTrace();
|
|
||||||
final java.lang.String exceptionName = getClass().getName();
|
|
||||||
int startIdx = 1;
|
|
||||||
while (startIdx < elements.length && !isConstructorFor(elements[startIdx], exceptionName)) {
|
|
||||||
++startIdx;
|
|
||||||
}
|
|
||||||
while (startIdx < elements.length && isConstructorFor(elements[startIdx], exceptionName)) {
|
|
||||||
++startIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
int endIdx = startIdx;
|
|
||||||
while (endIdx < elements.length && !TaskTypes.isEntryPoint(elements[endIdx])) {
|
|
||||||
++endIdx;
|
|
||||||
}
|
|
||||||
stackTrace = (startIdx == elements.length) ? NO_STACK_TRACE : DJVM.copyToDJVM(elements, startIdx, endIdx);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isConstructorFor(java.lang.StackTraceElement elt, java.lang.String className) {
|
|
||||||
return elt.getClassName().equals(className) && elt.getMethodName().equals("<init>");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void printStackTrace() {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
java.lang.Throwable fromDJVM() {
|
|
||||||
return DJVM.fromDJVM(this);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package sandbox.java.nio.charset;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class that implements just enough of {@link java.nio.charset.Charset}
|
|
||||||
* to allow us to compile {@link sandbox.java.lang.String}.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public abstract class Charset extends sandbox.java.lang.Object {
|
|
||||||
private final sandbox.java.lang.String canonicalName;
|
|
||||||
|
|
||||||
protected Charset(sandbox.java.lang.String canonicalName, sandbox.java.lang.String[] aliases) {
|
|
||||||
this.canonicalName = canonicalName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final sandbox.java.lang.String name() {
|
|
||||||
return canonicalName;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
package sandbox.java.util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class that implements just enough of {@link java.util.Comparator}
|
|
||||||
* to allow us to compile {@link sandbox.java.lang.String}.
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface Comparator<T> extends java.util.Comparator<T> {
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package sandbox.java.util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class to bootstrap us into the sandbox.
|
|
||||||
*/
|
|
||||||
public class LinkedHashMap<K, V> extends java.util.LinkedHashMap<K, V> implements Map<K, V> {
|
|
||||||
public LinkedHashMap(int initialSize) {
|
|
||||||
super(initialSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LinkedHashMap() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
package sandbox.java.util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class that implements just enough of {@link java.util.Locale}
|
|
||||||
* to allow us to compile {@link sandbox.java.lang.String}.
|
|
||||||
*/
|
|
||||||
public abstract class Locale extends sandbox.java.lang.Object {
|
|
||||||
public abstract sandbox.java.lang.String toLanguageTag();
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package sandbox.java.util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class to bootstrap us into the sandbox.
|
|
||||||
*/
|
|
||||||
public interface Map<K, V> extends java.util.Map<K, V> {
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package sandbox.java.util.function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class that implements just enough of {@link java.util.function.Function}
|
|
||||||
* to allow us to compile {@link sandbox.Task}.
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface Function<T, R> {
|
|
||||||
R apply(T item);
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package sandbox.java.util.function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a dummy class that implements just enough of @{link java.util.function.Supplier}
|
|
||||||
* to allow us to compile {@link sandbox.java.lang.ThreadLocal}.
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface Supplier<T> {
|
|
||||||
T get();
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package sandbox.sun.misc;
|
|
||||||
|
|
||||||
import sandbox.java.lang.Enum;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public interface JavaLangAccess {
|
|
||||||
|
|
||||||
<E extends Enum<E>> E[] getEnumConstantsShared(Class<E> enumClass);
|
|
||||||
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package sandbox.sun.misc;
|
|
||||||
|
|
||||||
import sandbox.java.lang.Enum;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class SharedSecrets extends sandbox.java.lang.Object {
|
|
||||||
private static final JavaLangAccess javaLangAccess = new JavaLangAccessImpl();
|
|
||||||
|
|
||||||
private static class JavaLangAccessImpl implements JavaLangAccess {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public <E extends Enum<E>> E[] getEnumConstantsShared(Class<E> enumClass) {
|
|
||||||
return (E[]) sandbox.java.lang.DJVM.getEnumConstantsShared(enumClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JavaLangAccess getJavaLangAccess() {
|
|
||||||
return javaLangAccess;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
package net.corda.djvm
|
|
||||||
|
|
||||||
import net.corda.djvm.analysis.AnalysisConfiguration
|
|
||||||
import net.corda.djvm.code.DefinitionProvider
|
|
||||||
import net.corda.djvm.code.EMIT_TRACING
|
|
||||||
import net.corda.djvm.code.Emitter
|
|
||||||
import net.corda.djvm.execution.ExecutionProfile
|
|
||||||
import net.corda.djvm.rewiring.SandboxClassLoader
|
|
||||||
import net.corda.djvm.rules.Rule
|
|
||||||
import net.corda.djvm.utilities.Discovery
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration to use for the deterministic sandbox.
|
|
||||||
*
|
|
||||||
* @property rules The rules to apply during the analysis phase.
|
|
||||||
* @property emitters The code emitters / re-writers to apply to all loaded classes.
|
|
||||||
* @property definitionProviders The meta-data providers to apply to class and member definitions.
|
|
||||||
* @property executionProfile The execution profile to use in the sandbox.
|
|
||||||
* @property analysisConfiguration The configuration used in the analysis of classes.
|
|
||||||
* @property parentClassLoader The [SandboxClassLoader] that this sandbox will use as a parent.
|
|
||||||
*/
|
|
||||||
class SandboxConfiguration private constructor(
|
|
||||||
val rules: List<Rule>,
|
|
||||||
val emitters: List<Emitter>,
|
|
||||||
val definitionProviders: List<DefinitionProvider>,
|
|
||||||
val executionProfile: ExecutionProfile,
|
|
||||||
val analysisConfiguration: AnalysisConfiguration,
|
|
||||||
val parentClassLoader: SandboxClassLoader?
|
|
||||||
) {
|
|
||||||
@Suppress("unused")
|
|
||||||
companion object {
|
|
||||||
/**
|
|
||||||
* Default configuration for the deterministic sandbox.
|
|
||||||
*/
|
|
||||||
@JvmField
|
|
||||||
val DEFAULT = SandboxConfiguration.of()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration with no emitters, rules, meta-data providers or runtime thresholds.
|
|
||||||
*/
|
|
||||||
@JvmField
|
|
||||||
val EMPTY = SandboxConfiguration.of(
|
|
||||||
ExecutionProfile.UNLIMITED, emptyList(), emptyList(), emptyList()
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a sandbox configuration where one or more properties deviates from the default.
|
|
||||||
*/
|
|
||||||
fun of(
|
|
||||||
profile: ExecutionProfile = ExecutionProfile.DEFAULT,
|
|
||||||
rules: List<Rule> = Discovery.find(),
|
|
||||||
emitters: List<Emitter>? = null,
|
|
||||||
definitionProviders: List<DefinitionProvider> = Discovery.find(),
|
|
||||||
enableTracing: Boolean = true,
|
|
||||||
analysisConfiguration: AnalysisConfiguration = AnalysisConfiguration.createRoot(),
|
|
||||||
parentClassLoader: SandboxClassLoader? = null
|
|
||||||
) = SandboxConfiguration(
|
|
||||||
executionProfile = profile,
|
|
||||||
rules = rules,
|
|
||||||
emitters = (emitters ?: Discovery.find()).filter {
|
|
||||||
enableTracing || it.priority > EMIT_TRACING
|
|
||||||
},
|
|
||||||
definitionProviders = definitionProviders,
|
|
||||||
analysisConfiguration = analysisConfiguration,
|
|
||||||
parentClassLoader = parentClassLoader
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user