├── konf-core ├── src │ ├── test │ │ ├── resources │ │ │ └── source │ │ │ │ └── provider.properties │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── uchuhimo │ │ │ │ └── konf │ │ │ │ ├── source │ │ │ │ ├── env │ │ │ │ │ └── env.properties │ │ │ │ ├── SourceNodeSpec.kt │ │ │ │ ├── base │ │ │ │ │ ├── ValueSourceSpec.kt │ │ │ │ │ ├── KVSourceSpec.kt │ │ │ │ │ └── MapSourceSpec.kt │ │ │ │ ├── json │ │ │ │ │ ├── JsonSourceLoadSpec.kt │ │ │ │ │ ├── JsonWriterSpec.kt │ │ │ │ │ └── JsonProviderSpec.kt │ │ │ │ ├── properties │ │ │ │ │ └── PropertiesSourceLoadSpec.kt │ │ │ │ ├── SourceInfoSpec.kt │ │ │ │ ├── deserializer │ │ │ │ │ ├── DurationDeserializerSpec.kt │ │ │ │ │ └── OffsetDateTimeDeserializerSpec.kt │ │ │ │ └── CustomDeserializerSpec.kt │ │ │ │ ├── NetworkBuffer.kt │ │ │ │ ├── AdHocNetworkBuffer.kt │ │ │ │ └── SizeInBytesSpec.kt │ │ └── java │ │ │ └── com │ │ │ └── uchuhimo │ │ │ └── konf │ │ │ ├── AnonymousConfigSpec.java │ │ │ └── NetworkBufferInJava.java │ ├── testFixtures │ │ └── kotlin │ │ │ └── com │ │ │ └── uchuhimo │ │ │ └── konf │ │ │ ├── TestUtils.kt │ │ │ └── source │ │ │ ├── SingleThreadDispatcher.kt │ │ │ ├── base │ │ │ ├── FlatConfigForLoad.kt │ │ │ └── FlatSourceLoadBaseSpec.kt │ │ │ └── TestUtils.kt │ └── main │ │ ├── kotlin │ │ └── com │ │ │ └── uchuhimo │ │ │ └── konf │ │ │ ├── source │ │ │ ├── deserializer │ │ │ │ ├── ZoneDateTimeDeserializer.kt │ │ │ │ ├── OffsetDateTimeDeserializer.kt │ │ │ │ ├── DurationDeserializer.kt │ │ │ │ ├── JSR310Deserializer.kt │ │ │ │ └── StringDeserializer.kt │ │ │ ├── base │ │ │ │ ├── ValueSource.kt │ │ │ │ ├── KVSource.kt │ │ │ │ └── MapSource.kt │ │ │ ├── json │ │ │ │ ├── JsonProvider.kt │ │ │ │ ├── JsonWriter.kt │ │ │ │ └── JsonSource.kt │ │ │ ├── properties │ │ │ │ ├── PropertiesProvider.kt │ │ │ │ └── PropertiesWriter.kt │ │ │ ├── Writer.kt │ │ │ ├── env │ │ │ │ └── EnvProvider.kt │ │ │ └── SourceNode.kt │ │ │ ├── annotation │ │ │ └── Annotations.kt │ │ │ ├── Prefix.kt │ │ │ ├── Feature.kt │ │ │ └── MergedMap.kt │ │ └── java │ │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── Configs.java └── build.gradle.kts ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── konf-all ├── src │ ├── snippet │ │ ├── resources │ │ │ └── server.json │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── uchuhimo │ │ │ │ └── konf │ │ │ │ └── snippet │ │ │ │ ├── Load.kt │ │ │ │ ├── Server.kt │ │ │ │ ├── Serialize.kt │ │ │ │ ├── Fork.kt │ │ │ │ ├── Export.kt │ │ │ │ ├── Config.kt │ │ │ │ └── QuickStart.kt │ │ └── java │ │ │ └── com │ │ │ └── uchuhimo │ │ │ └── konf │ │ │ └── snippet │ │ │ ├── ServerSpecInJava.java │ │ │ └── ServerInJava.java │ └── test │ │ └── kotlin │ │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ ├── MergeSourcesWithDifferentFeaturesSpec.kt │ │ └── MultiLayerConfigToValueSpec.kt └── build.gradle.kts ├── konf-yaml ├── build.gradle.kts └── src │ ├── testFixtures │ └── kotlin │ │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ └── YamlTestUtils.kt │ ├── main │ └── kotlin │ │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ ├── DefaultYamlProvider.kt │ │ ├── DefaultYamlLoader.kt │ │ └── yaml │ │ ├── YamlWriter.kt │ │ └── YamlProvider.kt │ └── test │ ├── kotlin │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ ├── DefaultYamlProviderSpec.kt │ │ ├── DefaultYamlLoaderSpec.kt │ │ └── yaml │ │ ├── YamlWriterSpec.kt │ │ └── YamlProviderSpec.kt │ └── resources │ └── source │ └── source.yaml ├── konf-git ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ └── DefaultGitProvider.kt │ └── test │ └── kotlin │ └── com │ └── uchuhimo │ └── konf │ └── source │ └── DefaultGitProviderSpec.kt ├── konf-hocon ├── build.gradle.kts └── src │ ├── testFixtures │ └── kotlin │ │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ └── HoconTestUtils.kt │ ├── main │ └── kotlin │ │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ ├── DefaultHoconProvider.kt │ │ ├── DefaultHoconLoader.kt │ │ └── hocon │ │ ├── HoconProvider.kt │ │ ├── HoconWriter.kt │ │ └── HoconSource.kt │ └── test │ ├── java │ └── com │ │ └── uchuhimo │ │ └── konf │ │ ├── NetworkBufferInJava.java │ │ └── LoaderJavaApiTest.java │ ├── kotlin │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ ├── DefaultHoconProviderSpec.kt │ │ ├── DefaultHoconLoaderSpec.kt │ │ └── hocon │ │ ├── HoconSourceLoadSpec.kt │ │ ├── HoconWriterSpec.kt │ │ └── HoconProviderSpec.kt │ └── resources │ └── source │ └── source.conf ├── gradle.properties ├── konf-toml ├── build.gradle.kts └── src │ ├── testFixtures │ └── kotlin │ │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ └── TomlTestUtils.kt │ ├── main │ └── kotlin │ │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ ├── DefaultTomlProvider.kt │ │ ├── DefaultTomlLoader.kt │ │ └── toml │ │ ├── TomlProvider.kt │ │ └── TomlWriter.kt │ └── test │ ├── kotlin │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ ├── DefaultTomlProviderSpec.kt │ │ ├── DefaultTomlLoaderSpec.kt │ │ └── toml │ │ ├── TomlSourceLoadSpec.kt │ │ ├── TomlValueSourceSpec.kt │ │ ├── TomlWriterSpec.kt │ │ └── TomlProviderSpec.kt │ └── resources │ └── source │ └── source.toml ├── konf-xml ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ ├── DefaultXmlProvider.kt │ │ ├── DefaultXmlLoader.kt │ │ └── xml │ │ ├── XmlProvider.kt │ │ └── XmlWriter.kt │ ├── testFixtures │ └── kotlin │ │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ └── XmlTestUtils.kt │ └── test │ └── kotlin │ └── com │ └── uchuhimo │ └── konf │ └── source │ ├── DefaultXmlProviderSpec.kt │ ├── DefaultXmlLoaderSpec.kt │ └── xml │ ├── XmlSourceLoadSpec.kt │ └── XmlWriterSpec.kt ├── konf-js ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── com │ │ └── uchuhimo │ │ └── konf │ │ └── source │ │ ├── DefaultJsProvider.kt │ │ ├── DefaultJsLoader.kt │ │ └── js │ │ ├── JsWriter.kt │ │ └── JsProvider.kt │ └── test │ └── kotlin │ └── com │ └── uchuhimo │ └── konf │ └── source │ ├── DefaultJsProviderSpec.kt │ ├── js │ ├── JsSourceLoadSpec.kt │ ├── JsWriterSpec.kt │ └── JsProviderSpec.kt │ └── DefaultJsLoaderSpec.kt ├── .travis.yml ├── .gitattributes ├── .github ├── workflows │ └── gradle.yml └── stale.yml ├── settings.gradle.kts ├── config └── spotless │ ├── apache-license-2.0.java │ └── apache-license-2.0.kt └── gradlew.bat /konf-core/src/test/resources/source/provider.properties: -------------------------------------------------------------------------------- 1 | type=resource -------------------------------------------------------------------------------- /konf-core/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | jmhImplementation(kotlin("stdlib", Versions.kotlin)) 3 | } 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uchuhimo/konf/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /konf-all/src/snippet/resources/server.json: -------------------------------------------------------------------------------- 1 | { 2 | "server": { 3 | "host": "127.0.0.1", 4 | "tcp_port": 8080 5 | } 6 | } -------------------------------------------------------------------------------- /konf-yaml/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":konf-core")) 3 | implementation("org.yaml", "snakeyaml", Versions.yaml) 4 | 5 | testImplementation(testFixtures(project(":konf-core"))) 6 | } 7 | -------------------------------------------------------------------------------- /konf-git/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":konf-core")) 3 | api("org.eclipse.jgit", "org.eclipse.jgit", Versions.jgit) 4 | 5 | testImplementation(testFixtures(project(":konf-core"))) 6 | } 7 | -------------------------------------------------------------------------------- /konf-hocon/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":konf-core")) 3 | implementation("com.typesafe", "config", Versions.hocon) 4 | 5 | testImplementation(testFixtures(project(":konf-core"))) 6 | } 7 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en_US 2 | org.gradle.caching=true 3 | org.gradle.vfs.watch=true 4 | #org.gradle.parallel=true 5 | #org.gradle.configureondemand=true 6 | -------------------------------------------------------------------------------- /konf-toml/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":konf-core")) 3 | implementation("com.moandjiezana.toml", "toml4j", Versions.toml4j) 4 | 5 | testImplementation(testFixtures(project(":konf-core"))) 6 | } 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /konf-xml/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":konf-core")) 3 | implementation("org.dom4j", "dom4j", Versions.dom4j) 4 | implementation("jaxen", "jaxen", Versions.jaxen) 5 | 6 | testImplementation(testFixtures(project(":konf-core"))) 7 | } 8 | -------------------------------------------------------------------------------- /konf-js/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api(project(":konf-core")) 3 | implementation("org.graalvm.sdk", "graal-sdk", Versions.graal) 4 | implementation("org.graalvm.js", "js", Versions.graal) 5 | 6 | testImplementation(testFixtures(project(":konf-core"))) 7 | } 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - oraclejdk11 5 | - openjdk8 6 | - openjdk11 7 | - openjdk15 8 | 9 | after_success: 10 | - bash <(curl -s https://codecov.io/bash) 11 | 12 | before_cache: 13 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 14 | - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ 15 | cache: 16 | directories: 17 | - $HOME/.gradle/caches/ 18 | - $HOME/.gradle/wrapper/ 19 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # text stuff 2 | * text=lf 3 | *.bat text eol=crlf 4 | *.cmd text eol=crlf 5 | *.java text eol=lf 6 | *.kt text eol=lf 7 | *.md text eol=lf 8 | *.properties text eol=lf 9 | *.scala text eol=lf 10 | *.sh text eol=lf 11 | .gitattributes text eol=lf 12 | .gitignore text eol=lf 13 | build.gradle text eol=lf 14 | gradlew text eol=lf 15 | gradlew.bat text eol=crlf 16 | gradle/wrapper/gradle-wrapper.properties text eol=lf 17 | 18 | #binary 19 | *.jar binary 20 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | name: Konf CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | name: Build on JDK ${{ matrix.java_version }} and ${{ matrix.os }} 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | java_version: [8, 11, 16] 12 | os: [ubuntu-latest, windows-latest, macOS-latest] 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Set up JDK ${{ matrix.java_version }} 17 | uses: actions/setup-java@v1 18 | with: 19 | java-version: ${{ matrix.java_version }} 20 | - name: Build with Gradle 21 | run: ./gradlew build 22 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | mavenCentral() 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = "konf" 9 | 10 | include( 11 | "konf-core", 12 | "konf-git", 13 | "konf-hocon", 14 | "konf-js", 15 | "konf-toml", 16 | "konf-xml", 17 | "konf-yaml", 18 | "konf-all" 19 | ) 20 | 21 | plugins { 22 | id("com.gradle.enterprise") version "3.0" 23 | } 24 | 25 | gradleEnterprise { 26 | buildScan { 27 | termsOfServiceUrl = "https://gradle.com/terms-of-service" 28 | termsOfServiceAgree = "yes" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /konf-all/build.gradle.kts: -------------------------------------------------------------------------------- 1 | sourceSets { 2 | register("snippet") 3 | } 4 | 5 | val snippetImplementation by configurations 6 | snippetImplementation.extendsFrom(configurations.implementation.get()) 7 | 8 | dependencies { 9 | for (name in listOf( 10 | ":konf-core", 11 | ":konf-git", 12 | ":konf-hocon", 13 | ":konf-toml", 14 | ":konf-xml", 15 | ":konf-yaml" 16 | )) { 17 | api(project(name)) 18 | testImplementation(testFixtures(project(name))) 19 | } 20 | 21 | snippetImplementation(sourceSets.main.get().output) 22 | val snippet by sourceSets 23 | testImplementation(snippet.output) 24 | } 25 | -------------------------------------------------------------------------------- /config/spotless/apache-license-2.0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | -------------------------------------------------------------------------------- /config/spotless/apache-license-2.0.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/source/env/env.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017-2019 the original author or authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | SOURCE_TEST_TYPE=env 17 | SOURCE_CAMELCASE=true -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | # Number of days of inactivity before an Issue or Pull Request becomes stale 4 | daysUntilStale: 90 5 | # Number of days of inactivity before a stale Issue or Pull Request is closed 6 | daysUntilClose: false 7 | # Issues or Pull Requests with these labels will never be considered stale 8 | exemptLabels: 9 | - bug 10 | - Announcement 11 | - help wanted 12 | - To investigate 13 | # Label to use when marking as stale 14 | staleLabel: stale 15 | # Comment to post when marking as stale. Set to `false` to disable 16 | markComment: > 17 | This issue has been automatically marked as stale because it has not had 18 | recent activity. It will be closed after 30 days if no further activity 19 | occurs, but feel free to re-open a closed issue if needed. -------------------------------------------------------------------------------- /konf-hocon/src/testFixtures/kotlin/com/uchuhimo/konf/source/HoconTestUtils.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | const val hoconContent = "source.test.type = conf" 20 | -------------------------------------------------------------------------------- /konf-core/src/test/java/com/uchuhimo/konf/AnonymousConfigSpec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf; 18 | 19 | public class AnonymousConfigSpec { 20 | public static Spec spec = new ConfigSpec() {}; 21 | } 22 | -------------------------------------------------------------------------------- /konf-toml/src/testFixtures/kotlin/com/uchuhimo/konf/source/TomlTestUtils.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | //language=TOML 20 | const val tomlContent = 21 | """ 22 | [source.test] 23 | type = "toml" 24 | """ 25 | -------------------------------------------------------------------------------- /konf-yaml/src/testFixtures/kotlin/com/uchuhimo/konf/source/YamlTestUtils.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | //language=YAML 20 | const val yamlContent = 21 | """ 22 | source: 23 | test: 24 | type: yaml 25 | """ 26 | -------------------------------------------------------------------------------- /konf-js/src/main/kotlin/com/uchuhimo/konf/source/DefaultJsProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.uchuhimo.konf.source.js.JsProvider 20 | 21 | /** 22 | * Provider for JavaScript source. 23 | */ 24 | val DefaultProviders.js get() = JsProvider 25 | -------------------------------------------------------------------------------- /konf-xml/src/main/kotlin/com/uchuhimo/konf/source/DefaultXmlProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.uchuhimo.konf.source.xml.XmlProvider 20 | 21 | /** 22 | * Provider for XML source. 23 | */ 24 | val DefaultProviders.xml get() = XmlProvider 25 | -------------------------------------------------------------------------------- /konf-toml/src/main/kotlin/com/uchuhimo/konf/source/DefaultTomlProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.uchuhimo.konf.source.toml.TomlProvider 20 | 21 | /** 22 | * Provider for TOML source. 23 | */ 24 | val DefaultProviders.toml get() = TomlProvider 25 | -------------------------------------------------------------------------------- /konf-yaml/src/main/kotlin/com/uchuhimo/konf/source/DefaultYamlProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.uchuhimo.konf.source.yaml.YamlProvider 20 | 21 | /** 22 | * Provider for YAML source. 23 | */ 24 | val DefaultProviders.yaml get() = YamlProvider 25 | -------------------------------------------------------------------------------- /konf-hocon/src/main/kotlin/com/uchuhimo/konf/source/DefaultHoconProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.uchuhimo.konf.source.hocon.HoconProvider 20 | 21 | /** 22 | * Provider for HOCON source. 23 | */ 24 | val DefaultProviders.hocon get() = HoconProvider 25 | -------------------------------------------------------------------------------- /konf-xml/src/main/kotlin/com/uchuhimo/konf/source/DefaultXmlLoader.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.uchuhimo.konf.source.xml.XmlProvider 20 | 21 | /** 22 | * Loader for XML source. 23 | */ 24 | val DefaultLoaders.xml get() = Loader(config, XmlProvider.orMapped()) 25 | -------------------------------------------------------------------------------- /konf-js/src/main/kotlin/com/uchuhimo/konf/source/DefaultJsLoader.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.uchuhimo.konf.source.js.JsProvider 20 | 21 | /** 22 | * Loader for JavaScript source. 23 | */ 24 | val DefaultLoaders.js get() = Loader(config, JsProvider.orMapped()) 25 | -------------------------------------------------------------------------------- /konf-toml/src/main/kotlin/com/uchuhimo/konf/source/DefaultTomlLoader.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.uchuhimo.konf.source.toml.TomlProvider 20 | 21 | /** 22 | * Loader for TOML source. 23 | */ 24 | val DefaultLoaders.toml get() = Loader(config, TomlProvider.orMapped()) 25 | -------------------------------------------------------------------------------- /konf-yaml/src/main/kotlin/com/uchuhimo/konf/source/DefaultYamlLoader.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.uchuhimo.konf.source.yaml.YamlProvider 20 | 21 | /** 22 | * Loader for YAML source. 23 | */ 24 | val DefaultLoaders.yaml get() = Loader(config, YamlProvider.orMapped()) 25 | -------------------------------------------------------------------------------- /konf-hocon/src/main/kotlin/com/uchuhimo/konf/source/DefaultHoconLoader.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.uchuhimo.konf.source.hocon.HoconProvider 20 | 21 | /** 22 | * Loader for HOCON source. 23 | */ 24 | val DefaultLoaders.hocon get() = Loader(config, HoconProvider.orMapped()) 25 | -------------------------------------------------------------------------------- /konf-core/src/testFixtures/kotlin/com/uchuhimo/konf/TestUtils.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf 18 | 19 | import java.io.File 20 | 21 | fun tempFileOf(content: String, prefix: String = "tmp", suffix: String = ".tmp"): File { 22 | return tempFile(prefix, suffix).apply { 23 | writeText(content) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /konf-hocon/src/test/java/com/uchuhimo/konf/NetworkBufferInJava.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf; 18 | 19 | public class NetworkBufferInJava { 20 | public static final ConfigSpec spec = new ConfigSpec("network.buffer"); 21 | 22 | public static final RequiredItem size = 23 | new RequiredItem(spec, "size", "size of buffer in KB") {}; 24 | } 25 | -------------------------------------------------------------------------------- /konf-xml/src/testFixtures/kotlin/com/uchuhimo/konf/source/XmlTestUtils.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | //language=XML 20 | val xmlContent = 21 | """ 22 | 23 | 24 | 25 | source.test.type 26 | xml 27 | 28 | 29 | """.trim() 30 | -------------------------------------------------------------------------------- /konf-all/src/snippet/kotlin/com/uchuhimo/konf/snippet/Load.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.snippet 18 | 19 | import com.uchuhimo.konf.Config 20 | 21 | fun main(args: Array) { 22 | val config = Config { addSpec(Server) } 23 | // values in source is loaded into new layer in child config 24 | val childConfig = config.from.env() 25 | check(childConfig.parent === config) 26 | } 27 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/deserializer/ZoneDateTimeDeserializer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.deserializer 18 | 19 | import java.time.ZonedDateTime 20 | 21 | /** 22 | * Deserializer for [ZonedDateTime]. 23 | */ 24 | object ZoneDateTimeDeserializer : JSR310Deserializer(ZonedDateTime::class.java) { 25 | override fun parse(string: String): ZonedDateTime = ZonedDateTime.parse(string) 26 | } 27 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/deserializer/OffsetDateTimeDeserializer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.deserializer 18 | 19 | import java.time.OffsetDateTime 20 | 21 | /** 22 | * Deserializer for [OffsetDateTime]. 23 | */ 24 | object OffsetDateTimeDeserializer : JSR310Deserializer(OffsetDateTime::class.java) { 25 | override fun parse(string: String): OffsetDateTime = OffsetDateTime.parse(string) 26 | } 27 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/annotation/Annotations.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.annotation 18 | 19 | /** 20 | * Indicates that this API is specially designed to be used in Java. 21 | */ 22 | @Target( 23 | AnnotationTarget.FUNCTION, 24 | AnnotationTarget.CONSTRUCTOR, 25 | AnnotationTarget.PROPERTY_GETTER, 26 | AnnotationTarget.PROPERTY_SETTER, 27 | AnnotationTarget.CLASS 28 | ) 29 | @Retention(AnnotationRetention.SOURCE) 30 | annotation class JavaApi 31 | -------------------------------------------------------------------------------- /konf-core/src/testFixtures/kotlin/com/uchuhimo/konf/source/SingleThreadDispatcher.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import kotlinx.coroutines.CoroutineDispatcher 20 | import kotlinx.coroutines.Dispatchers 21 | import kotlinx.coroutines.asCoroutineDispatcher 22 | import java.util.concurrent.Executors 23 | 24 | fun newSequentialDispatcher() = Executors.newSingleThreadExecutor().asCoroutineDispatcher() 25 | 26 | private val dispatcher = newSequentialDispatcher() 27 | 28 | val Dispatchers.Sequential: CoroutineDispatcher get() = dispatcher 29 | -------------------------------------------------------------------------------- /konf-all/src/snippet/java/com/uchuhimo/konf/snippet/ServerSpecInJava.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.snippet; 18 | 19 | import com.uchuhimo.konf.ConfigSpec; 20 | import com.uchuhimo.konf.OptionalItem; 21 | import com.uchuhimo.konf.RequiredItem; 22 | 23 | public class ServerSpecInJava { 24 | public static final ConfigSpec spec = new ConfigSpec("server"); 25 | 26 | public static final OptionalItem host = 27 | new OptionalItem(spec, "host", "0.0.0.0") {}; 28 | 29 | public static final RequiredItem tcpPort = new RequiredItem(spec, "tcpPort") {}; 30 | } 31 | -------------------------------------------------------------------------------- /konf-all/src/snippet/kotlin/com/uchuhimo/konf/snippet/Server.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.snippet 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.ConfigSpec 21 | 22 | data class Server(val host: String, val tcpPort: Int) { 23 | constructor(config: Config) : this(config[Server.host], config[Server.tcpPort]) 24 | 25 | fun start() {} 26 | 27 | companion object : ConfigSpec("server") { 28 | val host by optional("0.0.0.0", description = "host IP of server") 29 | val tcpPort by required(description = "port of server") 30 | val nextPort by lazy { config -> config[tcpPort] + 1 } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /konf-all/src/snippet/java/com/uchuhimo/konf/snippet/ServerInJava.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.snippet; 18 | 19 | import com.uchuhimo.konf.Config; 20 | 21 | public class ServerInJava { 22 | private String host; 23 | private Integer tcpPort; 24 | 25 | public ServerInJava(String host, Integer tcpPort) { 26 | this.host = host; 27 | this.tcpPort = tcpPort; 28 | } 29 | 30 | public ServerInJava(Config config) { 31 | this(config.get(ServerSpecInJava.host), config.get(ServerSpecInJava.tcpPort)); 32 | } 33 | 34 | public String getHost() { 35 | return host; 36 | } 37 | 38 | public Integer getTcpPort() { 39 | return tcpPort; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/base/ValueSource.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.base 18 | 19 | import com.uchuhimo.konf.TreeNode 20 | import com.uchuhimo.konf.notEmptyOr 21 | import com.uchuhimo.konf.source.Source 22 | import com.uchuhimo.konf.source.SourceInfo 23 | import com.uchuhimo.konf.source.asTree 24 | 25 | /** 26 | * Source from a single value. 27 | */ 28 | open class ValueSource( 29 | val value: Any, 30 | type: String = "", 31 | final override val info: SourceInfo = SourceInfo() 32 | ) : Source { 33 | init { 34 | info["type"] = type.notEmptyOr("value") 35 | } 36 | 37 | override val tree: TreeNode = value.asTree() 38 | } 39 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/json/JsonProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.json 18 | 19 | import com.fasterxml.jackson.databind.ObjectMapper 20 | import com.uchuhimo.konf.annotation.JavaApi 21 | import com.uchuhimo.konf.source.Provider 22 | import com.uchuhimo.konf.source.Source 23 | import java.io.InputStream 24 | import java.io.Reader 25 | 26 | /** 27 | * Provider for JSON source. 28 | */ 29 | object JsonProvider : Provider { 30 | override fun reader(reader: Reader): Source = 31 | JsonSource(ObjectMapper().readTree(reader)) 32 | 33 | override fun inputStream(inputStream: InputStream): Source = 34 | JsonSource(ObjectMapper().readTree(inputStream)) 35 | 36 | @JavaApi 37 | @JvmStatic 38 | fun get() = this 39 | } 40 | -------------------------------------------------------------------------------- /konf-core/src/main/java/com/uchuhimo/konf/Configs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf; 18 | 19 | import java.util.function.Consumer; 20 | 21 | /** Helper class for {@link com.uchuhimo.konf.Config Config}. */ 22 | public final class Configs { 23 | private Configs() {} 24 | 25 | /** 26 | * Create a new root config. 27 | * 28 | * @return a new root config 29 | */ 30 | public static Config create() { 31 | return Config.Companion.invoke(); 32 | } 33 | 34 | /** 35 | * Create a new root config and initiate it. 36 | * 37 | * @param init initial action 38 | * @return a new root config 39 | */ 40 | public static Config create(Consumer init) { 41 | final Config config = create(); 42 | init.accept(config); 43 | return config; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/deserializer/DurationDeserializer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.deserializer 18 | 19 | import com.uchuhimo.konf.source.SourceException 20 | import com.uchuhimo.konf.source.toDuration 21 | import java.time.Duration 22 | import java.time.format.DateTimeParseException 23 | 24 | /** 25 | * Deserializer for [Duration]. 26 | */ 27 | object DurationDeserializer : JSR310Deserializer(Duration::class.java) { 28 | override fun parse(string: String): Duration { 29 | return try { 30 | Duration.parse(string) 31 | } catch (exception: DateTimeParseException) { 32 | try { 33 | string.toDuration() 34 | } catch (_: SourceException) { 35 | throw exception 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /konf-all/src/snippet/kotlin/com/uchuhimo/konf/snippet/Serialize.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.snippet 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.tempFile 21 | import java.io.ObjectInputStream 22 | import java.io.ObjectOutputStream 23 | 24 | fun main(args: Array) { 25 | val config = Config { addSpec(Server) } 26 | config[Server.tcpPort] = 1000 27 | val map = config.toMap() 28 | val newMap = tempFile().run { 29 | ObjectOutputStream(outputStream()).use { 30 | it.writeObject(map) 31 | } 32 | ObjectInputStream(inputStream()).use { 33 | @Suppress("UNCHECKED_CAST") 34 | it.readObject() as Map 35 | } 36 | } 37 | val newConfig = Config { 38 | addSpec(Server) 39 | }.from.map.kv(newMap) 40 | check(config.toMap() == newConfig.toMap()) 41 | } 42 | -------------------------------------------------------------------------------- /konf-all/src/snippet/kotlin/com/uchuhimo/konf/snippet/Fork.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.snippet 18 | 19 | import com.uchuhimo.konf.Config 20 | 21 | fun main(args: Array) { 22 | val config = Config { addSpec(Server) } 23 | config[Server.tcpPort] = 1000 24 | // fork from parent config 25 | val childConfig = config.withLayer("child") 26 | // child config inherit values from parent config 27 | check(childConfig[Server.tcpPort] == 1000) 28 | // modifications in parent config affect values in child config 29 | config[Server.tcpPort] = 2000 30 | check(config[Server.tcpPort] == 2000) 31 | check(childConfig[Server.tcpPort] == 2000) 32 | // modifications in child config don't affect values in parent config 33 | childConfig[Server.tcpPort] = 3000 34 | check(config[Server.tcpPort] == 2000) 35 | check(childConfig[Server.tcpPort] == 3000) 36 | } 37 | -------------------------------------------------------------------------------- /konf-all/src/snippet/kotlin/com/uchuhimo/konf/snippet/Export.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.snippet 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.source.base.toFlatMap 21 | import com.uchuhimo.konf.source.base.toHierarchicalMap 22 | import com.uchuhimo.konf.source.json.toJson 23 | import com.uchuhimo.konf.tempFile 24 | 25 | fun main(args: Array) { 26 | val config = Config { addSpec(Server) } 27 | config[Server.tcpPort] = 1000 28 | run { 29 | val map = config.toMap() 30 | } 31 | run { 32 | val map = config.toHierarchicalMap() 33 | } 34 | run { 35 | val map = config.toFlatMap() 36 | } 37 | val file = tempFile(suffix = ".json") 38 | config.toJson.toFile(file) 39 | val newConfig = Config { 40 | addSpec(Server) 41 | }.from.json.file(file) 42 | check(config.toMap() == newConfig.toMap()) 43 | } 44 | -------------------------------------------------------------------------------- /konf-toml/src/main/kotlin/com/uchuhimo/konf/source/toml/TomlProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.toml 18 | 19 | import com.moandjiezana.toml.Toml 20 | import com.uchuhimo.konf.annotation.JavaApi 21 | import com.uchuhimo.konf.source.Provider 22 | import com.uchuhimo.konf.source.RegisterExtension 23 | import com.uchuhimo.konf.source.Source 24 | import com.uchuhimo.konf.source.asSource 25 | import java.io.InputStream 26 | import java.io.Reader 27 | 28 | /** 29 | * Provider for TOML source. 30 | */ 31 | @RegisterExtension(["toml"]) 32 | object TomlProvider : Provider { 33 | override fun reader(reader: Reader): Source = 34 | Toml().read(reader).toMap().asSource(type = "TOML") 35 | 36 | override fun inputStream(inputStream: InputStream): Source = 37 | Toml().read(inputStream).toMap().asSource(type = "TOML") 38 | 39 | @JavaApi 40 | @JvmStatic 41 | fun get() = this 42 | } 43 | -------------------------------------------------------------------------------- /konf-hocon/src/main/kotlin/com/uchuhimo/konf/source/hocon/HoconProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.hocon 18 | 19 | import com.typesafe.config.ConfigFactory 20 | import com.uchuhimo.konf.annotation.JavaApi 21 | import com.uchuhimo.konf.source.Provider 22 | import com.uchuhimo.konf.source.RegisterExtension 23 | import com.uchuhimo.konf.source.Source 24 | import java.io.InputStream 25 | import java.io.Reader 26 | 27 | /** 28 | * Provider for HOCON source. 29 | */ 30 | @RegisterExtension(["conf"]) 31 | object HoconProvider : Provider { 32 | override fun reader(reader: Reader): Source = 33 | HoconSource(ConfigFactory.parseReader(reader).resolve()) 34 | 35 | override fun inputStream(inputStream: InputStream): Source { 36 | inputStream.reader().use { 37 | return reader(it) 38 | } 39 | } 40 | 41 | @JavaApi 42 | @JvmStatic 43 | fun get() = this 44 | } 45 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/base/KVSource.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.base 18 | 19 | import com.uchuhimo.konf.ContainerNode 20 | import com.uchuhimo.konf.TreeNode 21 | import com.uchuhimo.konf.notEmptyOr 22 | import com.uchuhimo.konf.source.SourceInfo 23 | import com.uchuhimo.konf.source.asTree 24 | 25 | /** 26 | * Source from a map in key-value format. 27 | */ 28 | open class KVSource( 29 | val map: Map, 30 | type: String = "", 31 | info: SourceInfo = SourceInfo() 32 | ) : ValueSource(map, type.notEmptyOr("KV"), info) { 33 | override val tree: TreeNode = map.kvToTree() 34 | } 35 | 36 | fun Map.kvToTree(): TreeNode { 37 | return ContainerNode(mutableMapOf()).apply { 38 | this@kvToTree.forEach { (path, value) -> 39 | set(path, value.asTree()) 40 | } 41 | } 42 | } 43 | 44 | fun Map.asKVSource() = KVSource(this) 45 | -------------------------------------------------------------------------------- /konf-js/src/test/kotlin/com/uchuhimo/konf/source/DefaultJsProviderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.tempFileOf 22 | import org.jetbrains.spek.api.dsl.given 23 | import org.jetbrains.spek.api.dsl.it 24 | import org.jetbrains.spek.api.dsl.on 25 | import org.jetbrains.spek.subject.SubjectSpek 26 | 27 | object DefaultJsProviderSpec : SubjectSpek({ 28 | subject { Source.from } 29 | 30 | val item = DefaultLoadersConfig.type 31 | 32 | given("a provider") { 33 | on("provider source from JavaScript file") { 34 | val config = subject.file(tempFileOf(jsContent, suffix = ".js")).toConfig() 35 | it("should provide as auto-detected file format") { 36 | assertThat(config[item], equalTo("js")) 37 | } 38 | } 39 | } 40 | }) 41 | -------------------------------------------------------------------------------- /konf-xml/src/test/kotlin/com/uchuhimo/konf/source/DefaultXmlProviderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.tempFileOf 22 | import org.jetbrains.spek.api.dsl.given 23 | import org.jetbrains.spek.api.dsl.it 24 | import org.jetbrains.spek.api.dsl.on 25 | import org.jetbrains.spek.subject.SubjectSpek 26 | 27 | object DefaultXmlProviderSpec : SubjectSpek({ 28 | subject { Source.from } 29 | 30 | val item = DefaultLoadersConfig.type 31 | 32 | given("a provider") { 33 | on("provide source from XML file") { 34 | val config = subject.file(tempFileOf(xmlContent, suffix = ".xml")).toConfig() 35 | it("should provide as auto-detected file format") { 36 | assertThat(config[item], equalTo("xml")) 37 | } 38 | } 39 | } 40 | }) 41 | -------------------------------------------------------------------------------- /konf-toml/src/test/kotlin/com/uchuhimo/konf/source/DefaultTomlProviderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.tempFileOf 22 | import org.jetbrains.spek.api.dsl.given 23 | import org.jetbrains.spek.api.dsl.it 24 | import org.jetbrains.spek.api.dsl.on 25 | import org.jetbrains.spek.subject.SubjectSpek 26 | 27 | object DefaultTomlProviderSpec : SubjectSpek({ 28 | subject { Source.from } 29 | 30 | val item = DefaultLoadersConfig.type 31 | 32 | given("a provider") { 33 | on("provide source from TOML file") { 34 | val config = subject.file(tempFileOf(tomlContent, suffix = ".toml")).toConfig() 35 | it("should provide as auto-detected file format") { 36 | assertThat(config[item], equalTo("toml")) 37 | } 38 | } 39 | } 40 | }) 41 | -------------------------------------------------------------------------------- /konf-yaml/src/test/kotlin/com/uchuhimo/konf/source/DefaultYamlProviderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.tempFileOf 22 | import org.jetbrains.spek.api.dsl.given 23 | import org.jetbrains.spek.api.dsl.it 24 | import org.jetbrains.spek.api.dsl.on 25 | import org.jetbrains.spek.subject.SubjectSpek 26 | 27 | object DefaultYamlProviderSpec : SubjectSpek({ 28 | subject { Source.from } 29 | 30 | val item = DefaultLoadersConfig.type 31 | 32 | given("a provider") { 33 | on("provide source from YAML file") { 34 | val config = subject.file(tempFileOf(yamlContent, suffix = ".yaml")).toConfig() 35 | it("should provide as auto-detected file format") { 36 | assertThat(config[item], equalTo("yaml")) 37 | } 38 | } 39 | } 40 | }) 41 | -------------------------------------------------------------------------------- /konf-core/src/testFixtures/kotlin/com/uchuhimo/konf/source/base/FlatConfigForLoad.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.base 18 | 19 | import com.uchuhimo.konf.ConfigSpec 20 | import java.io.Serializable 21 | 22 | object FlatConfigForLoad : ConfigSpec("level1.level2") { 23 | val emptyList by required>() 24 | val emptySet by required>() 25 | val emptyArray by required() 26 | val emptyObjectArray by required>() 27 | val singleElementList by required>() 28 | val multipleElementsList by required>() 29 | val flatClass by required() 30 | } 31 | 32 | data class ClassForLoad( 33 | val stringWithComma: String, 34 | val emptyList: List, 35 | val emptySet: Set, 36 | val emptyArray: IntArray, 37 | val emptyObjectArray: Array, 38 | val singleElementList: List, 39 | val multipleElementsList: List 40 | ) : Serializable 41 | -------------------------------------------------------------------------------- /konf-hocon/src/test/kotlin/com/uchuhimo/konf/source/DefaultHoconProviderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.tempFileOf 22 | import org.jetbrains.spek.api.dsl.given 23 | import org.jetbrains.spek.api.dsl.it 24 | import org.jetbrains.spek.api.dsl.on 25 | import org.jetbrains.spek.subject.SubjectSpek 26 | 27 | object DefaultHoconProviderSpec : SubjectSpek({ 28 | subject { Source.from } 29 | 30 | val item = DefaultLoadersConfig.type 31 | 32 | given("a provider") { 33 | on("provider source from HOCON file") { 34 | val config = subject.file(tempFileOf(hoconContent, suffix = ".conf")).toConfig() 35 | it("should provide as auto-detected file format") { 36 | assertThat(config[item], equalTo("conf")) 37 | } 38 | } 39 | } 40 | }) 41 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/source/SourceNodeSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.EmptyNode 22 | import com.uchuhimo.konf.TreeNode 23 | import org.jetbrains.spek.api.dsl.it 24 | import org.jetbrains.spek.api.dsl.on 25 | import org.jetbrains.spek.subject.SubjectSpek 26 | 27 | object ListSourceNodeSpec : SubjectSpek({ 28 | subject { ListSourceNode(listOf(EmptyNode, EmptyNode)) } 29 | on("get children") { 30 | it("should return a map indexed by integer") { 31 | assertThat( 32 | subject.children, 33 | equalTo( 34 | mutableMapOf( 35 | "0" to EmptyNode, 36 | "1" to EmptyNode 37 | ) 38 | ) 39 | ) 40 | } 41 | } 42 | }) 43 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/NetworkBuffer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf 18 | 19 | class NetworkBuffer { 20 | companion object : ConfigSpec("network.buffer") { 21 | val size by required(description = "size of buffer in KB") 22 | 23 | val maxSize by lazy(description = "max size of buffer in KB") { it[size] * 2 } 24 | 25 | val name by optional("buffer", description = "name of buffer") 26 | 27 | val type by optional( 28 | Type.OFF_HEAP, 29 | description = 30 | """ 31 | | type of network buffer. 32 | | two type: 33 | | - on-heap 34 | | - off-heap 35 | | buffer is off-heap by default. 36 | """.trimMargin("| ") 37 | ) 38 | 39 | val offset by optional(null, description = "initial offset of buffer") 40 | } 41 | 42 | enum class Type { 43 | ON_HEAP, OFF_HEAP 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/AdHocNetworkBuffer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf 18 | 19 | class AdHocNetworkBuffer(config: Config) { 20 | private val root = config.at("network.buffer") 21 | 22 | val size: Int by root.required(description = "size of buffer in KB") 23 | 24 | val maxSize by root.lazy(name = "max-size", description = "max size of buffer in KB") { size * 2 } 25 | 26 | val name by root.optional("buffer", description = "name of buffer") 27 | 28 | val type by root.optional( 29 | Type.OFF_HEAP, 30 | prefix = "heap", 31 | description = 32 | """ 33 | | type of network buffer. 34 | | two type: 35 | | - on-heap 36 | | - off-heap 37 | | buffer is off-heap by default. 38 | """.trimMargin("| ") 39 | ) 40 | 41 | val offset by root.optional(null, description = "initial offset of buffer") 42 | 43 | enum class Type { 44 | ON_HEAP, OFF_HEAP 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /konf-xml/src/test/kotlin/com/uchuhimo/konf/source/DefaultXmlLoaderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.tempFileOf 23 | import org.jetbrains.spek.api.dsl.given 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | import org.jetbrains.spek.subject.SubjectSpek 27 | 28 | object DefaultXmlLoaderSpec : SubjectSpek({ 29 | subject { 30 | Config { 31 | addSpec(DefaultLoadersConfig) 32 | }.from 33 | } 34 | 35 | val item = DefaultLoadersConfig.type 36 | 37 | given("a loader") { 38 | on("load from XML file") { 39 | val config = subject.file(tempFileOf(xmlContent, suffix = ".xml")) 40 | it("should load as auto-detected file format") { 41 | assertThat(config[item], equalTo("xml")) 42 | } 43 | } 44 | } 45 | }) 46 | -------------------------------------------------------------------------------- /konf-toml/src/test/kotlin/com/uchuhimo/konf/source/DefaultTomlLoaderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.tempFileOf 23 | import org.jetbrains.spek.api.dsl.given 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | import org.jetbrains.spek.subject.SubjectSpek 27 | 28 | object DefaultTomlLoaderSpec : SubjectSpek({ 29 | subject { 30 | Config { 31 | addSpec(DefaultLoadersConfig) 32 | }.from 33 | } 34 | 35 | val item = DefaultLoadersConfig.type 36 | 37 | given("a loader") { 38 | on("load from TOML file") { 39 | val config = subject.file(tempFileOf(tomlContent, suffix = ".toml")) 40 | it("should load as auto-detected file format") { 41 | assertThat(config[item], equalTo("toml")) 42 | } 43 | } 44 | } 45 | }) 46 | -------------------------------------------------------------------------------- /konf-yaml/src/test/kotlin/com/uchuhimo/konf/source/DefaultYamlLoaderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.tempFileOf 23 | import org.jetbrains.spek.api.dsl.given 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | import org.jetbrains.spek.subject.SubjectSpek 27 | 28 | object DefaultYamlLoaderSpec : SubjectSpek({ 29 | subject { 30 | Config { 31 | addSpec(DefaultLoadersConfig) 32 | }.from 33 | } 34 | 35 | val item = DefaultLoadersConfig.type 36 | 37 | given("a loader") { 38 | on("load from YAML file") { 39 | val config = subject.file(tempFileOf(yamlContent, suffix = ".yaml")) 40 | it("should load as auto-detected file format") { 41 | assertThat(config[item], equalTo("yaml")) 42 | } 43 | } 44 | } 45 | }) 46 | -------------------------------------------------------------------------------- /konf-core/src/testFixtures/kotlin/com/uchuhimo/konf/source/TestUtils.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.Matcher 20 | import com.natpryce.hamkrest.assertion.assertThat 21 | import com.natpryce.hamkrest.has 22 | import com.natpryce.hamkrest.isA 23 | import com.natpryce.hamkrest.throws 24 | import com.uchuhimo.konf.Config 25 | import com.uchuhimo.konf.ConfigSpec 26 | 27 | object DefaultLoadersConfig : ConfigSpec("source.test") { 28 | val type by required() 29 | } 30 | 31 | fun Source.toConfig(): Config = Config { 32 | addSpec(DefaultLoadersConfig) 33 | }.withSource(this) 34 | 35 | inline fun assertCausedBy(noinline block: () -> Unit) { 36 | @Suppress("UNCHECKED_CAST") 37 | assertThat( 38 | block, 39 | throws( 40 | has( 41 | LoadException::cause, 42 | isA() as Matcher 43 | ) 44 | ) 45 | ) 46 | } 47 | 48 | const val propertiesContent = "source.test.type = properties" 49 | -------------------------------------------------------------------------------- /konf-hocon/src/test/kotlin/com/uchuhimo/konf/source/DefaultHoconLoaderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.tempFileOf 23 | import org.jetbrains.spek.api.dsl.given 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | import org.jetbrains.spek.subject.SubjectSpek 27 | 28 | object DefaultHoconLoaderSpec : SubjectSpek({ 29 | subject { 30 | Config { 31 | addSpec(DefaultLoadersConfig) 32 | }.from 33 | } 34 | 35 | val item = DefaultLoadersConfig.type 36 | 37 | given("a loader") { 38 | on("load from HOCON file") { 39 | val config = subject.file(tempFileOf(hoconContent, suffix = ".conf")) 40 | it("should load as auto-detected file format") { 41 | assertThat(config[item], equalTo("conf")) 42 | } 43 | } 44 | } 45 | }) 46 | -------------------------------------------------------------------------------- /konf-toml/src/main/kotlin/com/uchuhimo/konf/source/toml/TomlWriter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.toml 18 | 19 | import com.moandjiezana.toml.Toml4jWriter 20 | import com.uchuhimo.konf.Config 21 | import com.uchuhimo.konf.source.Writer 22 | import com.uchuhimo.konf.source.base.toHierarchicalMap 23 | import java.io.OutputStream 24 | 25 | /** 26 | * Writer for TOML source. 27 | */ 28 | class TomlWriter(val config: Config) : Writer { 29 | private val toml4jWriter = Toml4jWriter() 30 | 31 | override fun toWriter(writer: java.io.Writer) { 32 | writer.write(toText()) 33 | } 34 | 35 | override fun toOutputStream(outputStream: OutputStream) { 36 | outputStream.writer().use { 37 | toWriter(it) 38 | } 39 | } 40 | 41 | override fun toText(): String { 42 | return toml4jWriter.write(config.toHierarchicalMap()).replace("\n", System.lineSeparator()) 43 | } 44 | } 45 | 46 | /** 47 | * Returns writer for TOML source. 48 | */ 49 | val Config.toToml: Writer get() = TomlWriter(this) 50 | -------------------------------------------------------------------------------- /konf-hocon/src/test/java/com/uchuhimo/konf/LoaderJavaApiTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf; 18 | 19 | import static org.hamcrest.MatcherAssert.assertThat; 20 | import static org.hamcrest.Matchers.equalTo; 21 | 22 | import com.uchuhimo.konf.source.hocon.HoconProvider; 23 | import org.junit.jupiter.api.BeforeEach; 24 | import org.junit.jupiter.api.DisplayName; 25 | import org.junit.jupiter.api.Test; 26 | 27 | @DisplayName("test Java API of loader") 28 | class LoaderJavaApiTest { 29 | private Config config; 30 | 31 | @BeforeEach 32 | void initConfig() { 33 | config = Configs.create(); 34 | config.addSpec(NetworkBufferInJava.spec); 35 | } 36 | 37 | @Test 38 | @DisplayName("test fluent API to load from default loader") 39 | void loadFromDefaultLoader() { 40 | final Config newConfig = 41 | config 42 | .from() 43 | .source(HoconProvider.get()) 44 | .string(config.nameOf(NetworkBufferInJava.size) + " = 1024"); 45 | assertThat(newConfig.get(NetworkBufferInJava.size), equalTo(1024)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/source/base/ValueSourceSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.base 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.sameInstance 21 | import com.natpryce.hamkrest.throws 22 | import com.uchuhimo.konf.source.NoSuchPathException 23 | import com.uchuhimo.konf.source.asSource 24 | import org.jetbrains.spek.api.Spek 25 | import org.jetbrains.spek.api.dsl.given 26 | import org.jetbrains.spek.api.dsl.it 27 | import org.jetbrains.spek.api.dsl.on 28 | 29 | object ValueSourceSpec : Spek({ 30 | given("a value source") { 31 | on("get with non-empty path") { 32 | it("should throw NoSuchPathException") { 33 | assertThat({ 1.asSource()["a"] }, throws()) 34 | } 35 | } 36 | on("invoke `asSource`") { 37 | val source = 1.asSource() 38 | it("should return itself") { 39 | assertThat(source.asSource(), sameInstance(source)) 40 | } 41 | } 42 | } 43 | }) 44 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/Prefix.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf 18 | 19 | import com.uchuhimo.konf.source.Source 20 | 21 | /** 22 | * Convenient class for constructing [Spec]/[Config]/[Source] with prefix. 23 | */ 24 | data class Prefix( 25 | /** 26 | * The path of the prefix 27 | */ 28 | val path: String = "" 29 | ) { 30 | /** 31 | * Returns a config spec with this prefix. 32 | * 33 | * @param spec the base config spec 34 | * @return a config spec with this prefix 35 | */ 36 | operator fun plus(spec: Spec): Spec = spec.withPrefix(path) 37 | 38 | /** 39 | * Returns a config with this prefix. 40 | * 41 | * @param config the base config 42 | * @return a config with this prefix 43 | */ 44 | operator fun plus(config: Config): Config = config.withPrefix(path) 45 | 46 | /** 47 | * Returns a source with this prefix. 48 | * 49 | * @param source the base source 50 | * @return a source with this prefix 51 | */ 52 | operator fun plus(source: Source): Source = source.withPrefix(path) 53 | } 54 | -------------------------------------------------------------------------------- /konf-js/src/main/kotlin/com/uchuhimo/konf/source/js/JsWriter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.js 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.source.Writer 21 | import com.uchuhimo.konf.source.base.toHierarchicalMap 22 | import java.io.OutputStream 23 | import java.util.regex.Pattern 24 | 25 | /** 26 | * Writer for JavaScript source. 27 | */ 28 | class JsWriter(val config: Config) : Writer { 29 | override fun toWriter(writer: java.io.Writer) { 30 | val jsonOutput = config.mapper 31 | .writerWithDefaultPrettyPrinter() 32 | .writeValueAsString(config.toHierarchicalMap()) 33 | val pattern = Pattern.compile("(\")(.*)(\"\\s*):") 34 | val jsOutput = pattern.matcher(jsonOutput).replaceAll("$2:") 35 | writer.write("($jsOutput)") 36 | } 37 | 38 | override fun toOutputStream(outputStream: OutputStream) { 39 | outputStream.writer().use { 40 | toWriter(it) 41 | } 42 | } 43 | } 44 | 45 | /** 46 | * Returns writer for JavaScript source. 47 | */ 48 | val Config.toJs: Writer get() = JsWriter(this) 49 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/source/json/JsonSourceLoadSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.json 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.Feature 21 | import com.uchuhimo.konf.source.ConfigForLoad 22 | import com.uchuhimo.konf.source.SourceLoadBaseSpec 23 | import org.jetbrains.spek.subject.SubjectSpek 24 | import org.jetbrains.spek.subject.itBehavesLike 25 | 26 | object JsonSourceLoadSpec : SubjectSpek({ 27 | 28 | subject { 29 | Config { 30 | addSpec(ConfigForLoad) 31 | enable(Feature.FAIL_ON_UNKNOWN_PATH) 32 | }.from.json.resource("source/source.json") 33 | } 34 | 35 | itBehavesLike(SourceLoadBaseSpec) 36 | }) 37 | 38 | object JsonSourceReloadSpec : SubjectSpek({ 39 | 40 | subject { 41 | val config = Config { 42 | addSpec(ConfigForLoad) 43 | }.from.json.resource("source/source.json") 44 | val json = config.toJson.toText() 45 | Config { 46 | addSpec(ConfigForLoad) 47 | }.from.json.string(json) 48 | } 49 | 50 | itBehavesLike(SourceLoadBaseSpec) 51 | }) 52 | -------------------------------------------------------------------------------- /konf-js/src/test/kotlin/com/uchuhimo/konf/source/js/JsSourceLoadSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.js 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.Feature 21 | import com.uchuhimo.konf.source.ConfigForLoad 22 | import com.uchuhimo.konf.source.SourceLoadBaseSpec 23 | import com.uchuhimo.konf.source.js 24 | import org.jetbrains.spek.subject.SubjectSpek 25 | import org.jetbrains.spek.subject.itBehavesLike 26 | 27 | object JsSourceLoadSpec : SubjectSpek({ 28 | 29 | subject { 30 | Config { 31 | addSpec(ConfigForLoad) 32 | enable(Feature.FAIL_ON_UNKNOWN_PATH) 33 | }.from.js.resource("source/source.js") 34 | } 35 | 36 | itBehavesLike(SourceLoadBaseSpec) 37 | }) 38 | 39 | object JsSourceReloadSpec : SubjectSpek({ 40 | 41 | subject { 42 | val config = Config { 43 | addSpec(ConfigForLoad) 44 | }.from.js.resource("source/source.js") 45 | val js = config.toJs.toText() 46 | Config { 47 | addSpec(ConfigForLoad) 48 | }.from.js.string(js) 49 | } 50 | 51 | itBehavesLike(SourceLoadBaseSpec) 52 | }) 53 | -------------------------------------------------------------------------------- /konf-toml/src/test/kotlin/com/uchuhimo/konf/source/toml/TomlSourceLoadSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.toml 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.Feature 21 | import com.uchuhimo.konf.source.ConfigForLoad 22 | import com.uchuhimo.konf.source.SourceLoadBaseSpec 23 | import com.uchuhimo.konf.source.toml 24 | import org.jetbrains.spek.subject.SubjectSpek 25 | import org.jetbrains.spek.subject.itBehavesLike 26 | 27 | object TomlSourceLoadSpec : SubjectSpek({ 28 | 29 | subject { 30 | Config { 31 | addSpec(ConfigForLoad) 32 | enable(Feature.FAIL_ON_UNKNOWN_PATH) 33 | }.from.toml.resource("source/source.toml") 34 | } 35 | 36 | itBehavesLike(SourceLoadBaseSpec) 37 | }) 38 | 39 | object TomlSourceReloadSpec : SubjectSpek({ 40 | 41 | subject { 42 | val config = Config { 43 | addSpec(ConfigForLoad) 44 | }.from.toml.resource("source/source.toml") 45 | val toml = config.toToml.toText() 46 | Config { 47 | addSpec(ConfigForLoad) 48 | }.from.toml.string(toml) 49 | } 50 | 51 | itBehavesLike(SourceLoadBaseSpec) 52 | }) 53 | -------------------------------------------------------------------------------- /konf-hocon/src/test/kotlin/com/uchuhimo/konf/source/hocon/HoconSourceLoadSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.hocon 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.Feature 21 | import com.uchuhimo.konf.source.ConfigForLoad 22 | import com.uchuhimo.konf.source.SourceLoadBaseSpec 23 | import com.uchuhimo.konf.source.hocon 24 | import org.jetbrains.spek.subject.SubjectSpek 25 | import org.jetbrains.spek.subject.itBehavesLike 26 | 27 | object HoconSourceLoadSpec : SubjectSpek({ 28 | 29 | subject { 30 | Config { 31 | addSpec(ConfigForLoad) 32 | enable(Feature.FAIL_ON_UNKNOWN_PATH) 33 | }.from.hocon.resource("source/source.conf") 34 | } 35 | 36 | itBehavesLike(SourceLoadBaseSpec) 37 | }) 38 | 39 | object HoconSourceReloadSpec : SubjectSpek({ 40 | 41 | subject { 42 | val config = Config { 43 | addSpec(ConfigForLoad) 44 | }.from.hocon.resource("source/source.conf") 45 | val hocon = config.toHocon.toText() 46 | Config { 47 | addSpec(ConfigForLoad) 48 | }.from.hocon.string(hocon) 49 | } 50 | 51 | itBehavesLike(SourceLoadBaseSpec) 52 | }) 53 | -------------------------------------------------------------------------------- /konf-js/src/test/kotlin/com/uchuhimo/konf/source/DefaultJsLoaderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.tempFileOf 23 | import org.jetbrains.spek.api.dsl.given 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | import org.jetbrains.spek.subject.SubjectSpek 27 | 28 | object DefaultJsLoaderSpec : SubjectSpek({ 29 | subject { 30 | Config { 31 | addSpec(DefaultLoadersConfig) 32 | }.from 33 | } 34 | 35 | val item = DefaultLoadersConfig.type 36 | 37 | given("a loader") { 38 | on("load from JavaScript file") { 39 | val config = subject.file(tempFileOf(jsContent, suffix = ".js")) 40 | it("should load as auto-detected file format") { 41 | assertThat(config[item], equalTo("js")) 42 | } 43 | } 44 | } 45 | }) 46 | 47 | //language=JavaScript 48 | const val jsContent = 49 | """ 50 | ({ 51 | source: { 52 | test: { 53 | type: "js" 54 | } 55 | } 56 | }) 57 | """ 58 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/json/JsonWriter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.json 18 | 19 | import com.fasterxml.jackson.core.util.DefaultIndenter 20 | import com.fasterxml.jackson.core.util.DefaultPrettyPrinter 21 | import com.fasterxml.jackson.databind.ObjectWriter 22 | import com.uchuhimo.konf.Config 23 | import com.uchuhimo.konf.source.Writer 24 | import com.uchuhimo.konf.source.base.toHierarchicalMap 25 | import java.io.OutputStream 26 | 27 | /** 28 | * Writer for JSON source. 29 | */ 30 | class JsonWriter(val config: Config) : Writer { 31 | private val objectWriter: ObjectWriter = config.mapper.writer( 32 | DefaultPrettyPrinter().withObjectIndenter( 33 | DefaultIndenter().withLinefeed(System.lineSeparator()) 34 | ) 35 | ) 36 | override fun toWriter(writer: java.io.Writer) { 37 | objectWriter.writeValue(writer, config.toHierarchicalMap()) 38 | } 39 | 40 | override fun toOutputStream(outputStream: OutputStream) { 41 | objectWriter.writeValue(outputStream, config.toHierarchicalMap()) 42 | } 43 | } 44 | 45 | /** 46 | * Returns Writer for JSON source. 47 | */ 48 | val Config.toJson: Writer get() = JsonWriter(this) 49 | -------------------------------------------------------------------------------- /konf-core/src/test/java/com/uchuhimo/konf/NetworkBufferInJava.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf; 18 | 19 | public class NetworkBufferInJava { 20 | public static final ConfigSpec spec = new ConfigSpec("network.buffer"); 21 | 22 | public static final RequiredItem size = 23 | new RequiredItem(spec, "size", "size of buffer in KB") {}; 24 | 25 | public static final LazyItem maxSize = 26 | new LazyItem( 27 | spec, "maxSize", config -> config.get(size) * 2, "max size of buffer in KB") {}; 28 | 29 | public static final OptionalItem name = 30 | new OptionalItem(spec, "name", "buffer", "name of buffer") {}; 31 | 32 | public static final OptionalItem type = 33 | new OptionalItem( 34 | spec, 35 | "type", 36 | NetworkBuffer.Type.OFF_HEAP, 37 | "type of network buffer.\n" 38 | + "two type:\n" 39 | + "- on-heap\n" 40 | + "- off-heap\n" 41 | + "buffer is off-heap by default.") {}; 42 | 43 | public static final OptionalItem offset = 44 | new OptionalItem(spec, "offset", null, "initial offset of buffer", null, true) {}; 45 | } 46 | -------------------------------------------------------------------------------- /konf-hocon/src/main/kotlin/com/uchuhimo/konf/source/hocon/HoconWriter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.hocon 18 | 19 | import com.typesafe.config.ConfigRenderOptions 20 | import com.typesafe.config.ConfigValueFactory 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.source.Writer 23 | import com.uchuhimo.konf.source.base.toHierarchicalMap 24 | import java.io.OutputStream 25 | 26 | /** 27 | * Writer for HOCON source. 28 | */ 29 | class HoconWriter(val config: Config) : Writer { 30 | private val renderOpts = ConfigRenderOptions.defaults() 31 | .setOriginComments(false) 32 | .setComments(false) 33 | .setJson(false) 34 | 35 | override fun toWriter(writer: java.io.Writer) { 36 | writer.write(toText()) 37 | } 38 | 39 | override fun toOutputStream(outputStream: OutputStream) { 40 | outputStream.writer().use { 41 | toWriter(it) 42 | } 43 | } 44 | 45 | override fun toText(): String { 46 | return ConfigValueFactory.fromMap(config.toHierarchicalMap()).render(renderOpts) 47 | .replace("\n", System.lineSeparator()) 48 | } 49 | } 50 | 51 | /** 52 | * Returns writer for HOCON source. 53 | */ 54 | val Config.toHocon: Writer get() = HoconWriter(this) 55 | -------------------------------------------------------------------------------- /konf-git/src/main/kotlin/com/uchuhimo/konf/source/DefaultGitProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import org.eclipse.jgit.lib.Constants 20 | import java.io.File 21 | 22 | /** 23 | * Returns a source from a specified git repository. 24 | * 25 | * Format of the url is auto-detected from the url extension. 26 | * Supported url formats and the corresponding extensions: 27 | * - HOCON: conf 28 | * - JSON: json 29 | * - Properties: properties 30 | * - TOML: toml 31 | * - XML: xml 32 | * - YAML: yml, yaml 33 | * 34 | * Throws [UnsupportedExtensionException] if the url extension is unsupported. 35 | * 36 | * @param repo git repository 37 | * @param file file in the git repository 38 | * @param dir local directory of the git repository 39 | * @param branch the initial branch 40 | * @param optional whether the source is optional 41 | * @return a source from a specified git repository 42 | * @throws UnsupportedExtensionException 43 | */ 44 | fun DefaultProviders.git( 45 | repo: String, 46 | file: String, 47 | dir: String? = null, 48 | branch: String = Constants.HEAD, 49 | optional: Boolean = false 50 | ): Source = dispatchExtension(File(file).extension, "{repo: $repo, file: $file}") 51 | .git(repo, file, dir, branch, optional) 52 | -------------------------------------------------------------------------------- /konf-xml/src/test/kotlin/com/uchuhimo/konf/source/xml/XmlSourceLoadSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.xml 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.source.ConfigForLoad 21 | import com.uchuhimo.konf.source.base.FlatConfigForLoad 22 | import com.uchuhimo.konf.source.base.FlatSourceLoadBaseSpec 23 | import com.uchuhimo.konf.source.xml 24 | import org.jetbrains.spek.subject.SubjectSpek 25 | import org.jetbrains.spek.subject.itBehavesLike 26 | 27 | object XmlSourceLoadSpec : SubjectSpek({ 28 | 29 | subject { 30 | Config { 31 | addSpec(ConfigForLoad) 32 | addSpec(FlatConfigForLoad) 33 | }.from.xml.resource("source/source.xml") 34 | } 35 | 36 | itBehavesLike(FlatSourceLoadBaseSpec) 37 | }) 38 | 39 | object XmlSourceReloadSpec : SubjectSpek({ 40 | 41 | subject { 42 | val config = Config { 43 | addSpec(ConfigForLoad) 44 | addSpec(FlatConfigForLoad) 45 | }.from.xml.resource("source/source.xml") 46 | val xml = config.toXml.toText() 47 | Config { 48 | addSpec(ConfigForLoad) 49 | addSpec(FlatConfigForLoad) 50 | }.from.xml.string(xml) 51 | } 52 | 53 | itBehavesLike(FlatSourceLoadBaseSpec) 54 | }) 55 | -------------------------------------------------------------------------------- /konf-yaml/src/main/kotlin/com/uchuhimo/konf/source/yaml/YamlWriter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.yaml 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.source.Writer 21 | import com.uchuhimo.konf.source.base.toHierarchicalMap 22 | import org.yaml.snakeyaml.DumperOptions 23 | import org.yaml.snakeyaml.Yaml 24 | import org.yaml.snakeyaml.constructor.SafeConstructor 25 | import org.yaml.snakeyaml.representer.Representer 26 | import java.io.OutputStream 27 | 28 | /** 29 | * Writer for YAML source. 30 | */ 31 | class YamlWriter(val config: Config) : Writer { 32 | private val yaml = Yaml( 33 | SafeConstructor(), 34 | Representer(), 35 | DumperOptions().apply { 36 | defaultFlowStyle = DumperOptions.FlowStyle.BLOCK 37 | lineBreak = DumperOptions.LineBreak.getPlatformLineBreak() 38 | } 39 | ) 40 | 41 | override fun toWriter(writer: java.io.Writer) { 42 | yaml.dump(config.toHierarchicalMap(), writer) 43 | } 44 | 45 | override fun toOutputStream(outputStream: OutputStream) { 46 | outputStream.writer().use { 47 | toWriter(it) 48 | } 49 | } 50 | } 51 | 52 | /** 53 | * Returns writer for YAML source. 54 | */ 55 | val Config.toYaml: Writer get() = YamlWriter(this) 56 | -------------------------------------------------------------------------------- /konf-all/src/test/kotlin/com/uchuhimo/konf/source/MergeSourcesWithDifferentFeaturesSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.ConfigSpec 23 | import org.jetbrains.spek.api.Spek 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | 27 | object MergeSourcesWithDifferentFeaturesSpec : Spek({ 28 | on("load from merged sources") { 29 | val config = Config { 30 | addSpec(ServicingConfig) 31 | }.withSource( 32 | Source.from.hocon.string(content) + Source.from.env() 33 | ) 34 | it("should contain the item") { 35 | assertThat(config[ServicingConfig.baseURL], equalTo("https://service/api")) 36 | assertThat(config[ServicingConfig.url], equalTo("https://service/api/index.html")) 37 | } 38 | } 39 | }) 40 | 41 | object ServicingConfig : ConfigSpec("servicing") { 42 | val baseURL by required() 43 | val url by required() 44 | } 45 | 46 | val content = """ 47 | servicing { 48 | baseURL = "https://service/api" 49 | url = "${'$'}{servicing.baseURL}/index.html" 50 | } 51 | """.trimIndent() 52 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/source/properties/PropertiesSourceLoadSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.properties 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.source.ConfigForLoad 21 | import com.uchuhimo.konf.source.base.FlatConfigForLoad 22 | import com.uchuhimo.konf.source.base.FlatSourceLoadBaseSpec 23 | import org.jetbrains.spek.subject.SubjectSpek 24 | import org.jetbrains.spek.subject.itBehavesLike 25 | 26 | object PropertiesSourceLoadSpec : SubjectSpek({ 27 | 28 | subject { 29 | Config { 30 | addSpec(ConfigForLoad) 31 | addSpec(FlatConfigForLoad) 32 | }.from.properties.resource("source/source.properties") 33 | } 34 | 35 | itBehavesLike(FlatSourceLoadBaseSpec) 36 | }) 37 | 38 | object PropertiesSourceReloadSpec : SubjectSpek({ 39 | 40 | subject { 41 | val config = Config { 42 | addSpec(ConfigForLoad) 43 | addSpec(FlatConfigForLoad) 44 | }.from.properties.resource("source/source.properties") 45 | val properties = config.toProperties.toText() 46 | Config { 47 | addSpec(ConfigForLoad) 48 | addSpec(FlatConfigForLoad) 49 | }.from.properties.string(properties) 50 | } 51 | 52 | itBehavesLike(FlatSourceLoadBaseSpec) 53 | }) 54 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/properties/PropertiesProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.properties 18 | 19 | import com.uchuhimo.konf.annotation.JavaApi 20 | import com.uchuhimo.konf.source.Provider 21 | import com.uchuhimo.konf.source.Source 22 | import com.uchuhimo.konf.source.base.FlatSource 23 | import java.io.InputStream 24 | import java.io.Reader 25 | import java.util.Properties 26 | 27 | /** 28 | * Provider for properties source. 29 | */ 30 | object PropertiesProvider : Provider { 31 | @Suppress("UNCHECKED_CAST") 32 | private fun Properties.toMap(): Map = this as Map 33 | 34 | override fun reader(reader: Reader): Source = 35 | FlatSource(Properties().apply { load(reader) }.toMap(), type = "properties") 36 | 37 | override fun inputStream(inputStream: InputStream): Source = 38 | FlatSource(Properties().apply { load(inputStream) }.toMap(), type = "properties") 39 | 40 | /** 41 | * Returns a new source from system properties. 42 | * 43 | * @return a new source from system properties 44 | */ 45 | fun system(): Source = FlatSource( 46 | System.getProperties().toMap(), 47 | type = "system-properties", 48 | allowConflict = true 49 | ) 50 | 51 | @JavaApi 52 | @JvmStatic 53 | fun get() = this 54 | } 55 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/Feature.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf 18 | 19 | /** 20 | * Enumeration that defines simple on/off features. 21 | */ 22 | enum class Feature(val enabledByDefault: Boolean) { 23 | /** 24 | * Feature that determines what happens when unknown paths appear in the source. 25 | * If enabled, an exception is thrown when loading from the source 26 | * to indicate it contains unknown paths. 27 | * 28 | * Feature is disabled by default. 29 | */ 30 | FAIL_ON_UNKNOWN_PATH(false), 31 | /** 32 | * Feature that determines whether loading keys from sources case-insensitively. 33 | * 34 | * Feature is disabled by default. 35 | */ 36 | LOAD_KEYS_CASE_INSENSITIVELY(false), 37 | /** 38 | * Feature that determines whether loading keys from sources as little camel case. 39 | * 40 | * Feature is enabled by default. 41 | */ 42 | LOAD_KEYS_AS_LITTLE_CAMEL_CASE(true), 43 | /** 44 | * Feature that determines whether sources are optional by default. 45 | * 46 | * Feature is disabled by default. 47 | */ 48 | OPTIONAL_SOURCE_BY_DEFAULT(false), 49 | /** 50 | * Feature that determines whether sources should be substituted before loaded into config. 51 | * 52 | * Feature is enabled by default. 53 | */ 54 | SUBSTITUTE_SOURCE_BEFORE_LOADED(true) 55 | } 56 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/source/SourceInfoSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import org.jetbrains.spek.api.dsl.given 22 | import org.jetbrains.spek.api.dsl.it 23 | import org.jetbrains.spek.api.dsl.on 24 | import org.jetbrains.spek.subject.SubjectSpek 25 | 26 | object SourceInfoSpec : SubjectSpek({ 27 | subject { SourceInfo("a" to "1") } 28 | 29 | given("a source info") { 30 | on("use as a map") { 31 | it("should behave like a map") { 32 | assertThat(subject.toMap(), equalTo(mapOf("a" to "1"))) 33 | } 34 | } 35 | on("with new KV pairs") { 36 | it("should contain the new KV pairs") { 37 | assertThat( 38 | subject.with("b" to "2", "c" to "3").toMap(), 39 | equalTo(mapOf("a" to "1", "b" to "2", "c" to "3")) 40 | ) 41 | } 42 | } 43 | on("with another source info") { 44 | it("should contain the new KV pairs in another source info") { 45 | assertThat( 46 | subject.with(SourceInfo("b" to "2", "c" to "3")).toMap(), 47 | equalTo(mapOf("a" to "1", "b" to "2", "c" to "3")) 48 | ) 49 | } 50 | } 51 | } 52 | }) 53 | -------------------------------------------------------------------------------- /konf-js/src/main/kotlin/com/uchuhimo/konf/source/js/JsProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.js 18 | 19 | import com.uchuhimo.konf.annotation.JavaApi 20 | import com.uchuhimo.konf.source.Provider 21 | import com.uchuhimo.konf.source.RegisterExtension 22 | import com.uchuhimo.konf.source.Source 23 | import com.uchuhimo.konf.source.json.JsonProvider 24 | import org.graalvm.polyglot.Context 25 | import java.io.InputStream 26 | import java.io.Reader 27 | import java.util.stream.Collectors 28 | 29 | /** 30 | * Provider for JavaScript source. 31 | */ 32 | @RegisterExtension(["js"]) 33 | object JsProvider : Provider { 34 | override fun reader(reader: Reader): Source { 35 | val sourceString = reader.buffered().lines().collect(Collectors.joining("\n")) 36 | Context.create().use { context -> 37 | val value = context.eval("js", sourceString) 38 | context.getBindings("js").putMember("source", value) 39 | val jsonString = context.eval("js", "JSON.stringify(source)").asString() 40 | return JsonProvider.string(jsonString).apply { 41 | this.info["type"] = "JavaScript" 42 | } 43 | } 44 | } 45 | 46 | override fun inputStream(inputStream: InputStream): Source { 47 | inputStream.reader().use { 48 | return reader(it) 49 | } 50 | } 51 | 52 | @JavaApi 53 | @JvmStatic 54 | fun get() = this 55 | } 56 | -------------------------------------------------------------------------------- /konf-xml/src/main/kotlin/com/uchuhimo/konf/source/xml/XmlProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.xml 18 | 19 | import com.uchuhimo.konf.annotation.JavaApi 20 | import com.uchuhimo.konf.source.Provider 21 | import com.uchuhimo.konf.source.RegisterExtension 22 | import com.uchuhimo.konf.source.Source 23 | import com.uchuhimo.konf.source.base.FlatSource 24 | import org.dom4j.Document 25 | import org.dom4j.io.SAXReader 26 | import java.io.InputStream 27 | import java.io.Reader 28 | 29 | /** 30 | * Provider for XML source. 31 | */ 32 | @RegisterExtension(["xml"]) 33 | object XmlProvider : Provider { 34 | private fun Document.toMap(): Map { 35 | val rootElement = this.rootElement 36 | val propertyNodes = rootElement.selectNodes("/configuration/property") 37 | return mutableMapOf().apply { 38 | for (property in propertyNodes) { 39 | put(property.selectSingleNode("name").text, property.selectSingleNode("value").text) 40 | } 41 | } 42 | } 43 | 44 | override fun reader(reader: Reader): Source { 45 | return FlatSource(SAXReader().read(reader).toMap(), type = "XML") 46 | } 47 | 48 | override fun inputStream(inputStream: InputStream): Source { 49 | return FlatSource(SAXReader().read(inputStream).toMap(), type = "XML") 50 | } 51 | 52 | @JavaApi 53 | @JvmStatic 54 | fun get() = this 55 | } 56 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/Writer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import java.io.File 20 | import java.io.OutputStream 21 | import java.io.StringWriter 22 | 23 | /** 24 | * Save config to various output format. 25 | */ 26 | interface Writer { 27 | /** 28 | * Save to specified writer. 29 | * 30 | * @param writer specified writer for writing character streams 31 | */ 32 | fun toWriter(writer: java.io.Writer) 33 | 34 | /** 35 | * Save to specified output stream. 36 | * 37 | * @param outputStream specified output stream of bytes 38 | */ 39 | fun toOutputStream(outputStream: OutputStream) 40 | 41 | /** 42 | * Save to specified file. 43 | * 44 | * @param file specified file 45 | * @return a new source from specified file 46 | */ 47 | fun toFile(file: File) { 48 | file.outputStream().use { 49 | toOutputStream(it) 50 | } 51 | } 52 | 53 | /** 54 | * Save to specified file path. 55 | * 56 | * @param file specified file path 57 | */ 58 | fun toFile(file: String) = toFile(File(file)) 59 | 60 | /** 61 | * Save to string. 62 | * 63 | * @return string 64 | */ 65 | fun toText(): String = StringWriter().apply { toWriter(this) }.toString() 66 | 67 | /** 68 | * Save to byte array. 69 | * 70 | * @return byte array 71 | */ 72 | fun toBytes(): ByteArray = toText().toByteArray() 73 | } 74 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/env/EnvProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.env 18 | 19 | import com.uchuhimo.konf.Feature 20 | import com.uchuhimo.konf.annotation.JavaApi 21 | import com.uchuhimo.konf.source.Source 22 | import com.uchuhimo.konf.source.base.FlatSource 23 | 24 | /** 25 | * Provider for system environment source. 26 | */ 27 | object EnvProvider { 28 | private val validEnv = Regex("(\\w+)(.\\w+)*") 29 | 30 | /** 31 | * Returns a new source from system environment. 32 | * 33 | * @param nested whether to treat "AA_BB_CC" as nested format "AA.BB.CC" or not. True by default. 34 | * @return a new source from system environment 35 | */ 36 | @JvmOverloads 37 | fun env(nested: Boolean = true): Source = envMap(System.getenv(), nested) 38 | 39 | @JvmOverloads 40 | fun envMap(map: Map, nested: Boolean = true): Source { 41 | return FlatSource( 42 | map.mapKeys { (key, _) -> 43 | if (nested) key.replace('_', '.') else key 44 | }.filter { (key, _) -> 45 | key.matches(validEnv) 46 | }.toSortedMap(), 47 | type = "system-environment", 48 | allowConflict = true 49 | ).enabled( 50 | Feature.LOAD_KEYS_CASE_INSENSITIVELY 51 | ).disabled( 52 | Feature.SUBSTITUTE_SOURCE_BEFORE_LOADED 53 | ) 54 | } 55 | 56 | @JavaApi 57 | @JvmStatic 58 | fun get() = this 59 | } 60 | -------------------------------------------------------------------------------- /konf-toml/src/test/kotlin/com/uchuhimo/konf/source/toml/TomlValueSourceSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.toml 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.natpryce.hamkrest.sameInstance 22 | import com.natpryce.hamkrest.throws 23 | import com.uchuhimo.konf.source.ParseException 24 | import com.uchuhimo.konf.source.asSource 25 | import com.uchuhimo.konf.source.asValue 26 | import org.jetbrains.spek.api.Spek 27 | import org.jetbrains.spek.api.dsl.given 28 | import org.jetbrains.spek.api.dsl.it 29 | import org.jetbrains.spek.api.dsl.on 30 | 31 | object TomlValueSourceSpec : Spek({ 32 | given("a TOML source") { 33 | on("get integer from long source") { 34 | it("should succeed") { 35 | assertThat(1L.asSource().asValue(), equalTo(1)) 36 | } 37 | } 38 | on("get integer from long source whose value is out of range of integer") { 39 | it("should throw ParseException") { 40 | assertThat({ Long.MAX_VALUE.asSource().asValue() }, throws()) 41 | assertThat({ Long.MIN_VALUE.asSource().asValue() }, throws()) 42 | } 43 | } 44 | on("invoke `asTomlSource`") { 45 | val source = 1.asSource() 46 | it("should return itself") { 47 | assertThat(source.asSource(), sameInstance(source)) 48 | } 49 | } 50 | } 51 | }) 52 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/SourceNode.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.uchuhimo.konf.ListNode 20 | import com.uchuhimo.konf.MapNode 21 | import com.uchuhimo.konf.NullNode 22 | import com.uchuhimo.konf.TreeNode 23 | import com.uchuhimo.konf.ValueNode 24 | import com.uchuhimo.konf.emptyMutableMap 25 | import java.util.Collections 26 | 27 | interface SubstitutableNode : ValueNode { 28 | fun substitute(value: String): TreeNode 29 | val substituted: Boolean 30 | val originalValue: Any? 31 | } 32 | 33 | class ValueSourceNode( 34 | override val value: Any, 35 | override val substituted: Boolean = false, 36 | override val originalValue: Any? = null 37 | ) : SubstitutableNode { 38 | override fun substitute(value: String): TreeNode { 39 | return ValueSourceNode(value, true, originalValue ?: this.value) 40 | } 41 | } 42 | 43 | object NullSourceNode : NullNode { 44 | override val children: MutableMap = emptyMutableMap 45 | } 46 | 47 | open class ListSourceNode( 48 | override val list: List, 49 | override var isPlaceHolder: Boolean = false 50 | ) : ListNode, MapNode { 51 | override val children: MutableMap 52 | get() = Collections.unmodifiableMap( 53 | list.withIndex().associate { (key, value) -> key.toString() to value } 54 | ) 55 | 56 | override fun withList(list: List): ListNode { 57 | return ListSourceNode(list) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /konf-all/src/test/kotlin/com/uchuhimo/konf/source/MultiLayerConfigToValueSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.fasterxml.jackson.databind.DeserializationFeature 20 | import com.natpryce.hamkrest.assertion.assertThat 21 | import com.natpryce.hamkrest.equalTo 22 | import com.uchuhimo.konf.Config 23 | import com.uchuhimo.konf.toValue 24 | import org.jetbrains.spek.api.Spek 25 | import org.jetbrains.spek.api.dsl.it 26 | import org.jetbrains.spek.api.dsl.on 27 | 28 | object MultiLayerConfigToValueSpec : Spek({ 29 | val yamlContent = """ 30 | db: 31 | driverClassName: org.h2.Driver 32 | url: 'jdbc:h2:mem:db;DB_CLOSE_DELAY=-1' 33 | """.trimIndent() 34 | 35 | val map = mapOf( 36 | "driverClassName" to "org.h2.Driver", 37 | "url" to "jdbc:h2:mem:db;DB_CLOSE_DELAY=-1" 38 | ) 39 | on("load from multiple sources") { 40 | val config = Config { 41 | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 42 | } 43 | .from.yaml.string(yamlContent) 44 | .from.yaml.file( 45 | System.getenv("SERVICE_CONFIG") 46 | ?: "/opt/legacy-event-service/conf/legacy-event-service.yml", 47 | true 48 | ) 49 | .from.systemProperties() 50 | .from.env() 51 | it("should cast to value correctly") { 52 | val db = config.toValue() 53 | assertThat(db.db, equalTo(map)) 54 | } 55 | } 56 | }) 57 | 58 | data class ConfigTestReport(val db: Map) 59 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/json/JsonSource.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.json 18 | 19 | import com.fasterxml.jackson.databind.JsonNode 20 | import com.uchuhimo.konf.ContainerNode 21 | import com.uchuhimo.konf.TreeNode 22 | import com.uchuhimo.konf.source.ListSourceNode 23 | import com.uchuhimo.konf.source.NullSourceNode 24 | import com.uchuhimo.konf.source.Source 25 | import com.uchuhimo.konf.source.SourceInfo 26 | import com.uchuhimo.konf.source.ValueSourceNode 27 | 28 | /** 29 | * Source from a JSON node. 30 | */ 31 | class JsonSource( 32 | val node: JsonNode 33 | ) : Source { 34 | override val info: SourceInfo = SourceInfo("type" to "JSON") 35 | 36 | override val tree: TreeNode = node.toTree() 37 | } 38 | 39 | fun JsonNode.toTree(): TreeNode { 40 | return when { 41 | isNull -> NullSourceNode 42 | isBoolean -> ValueSourceNode(booleanValue()) 43 | isNumber -> ValueSourceNode(numberValue()) 44 | isTextual -> ValueSourceNode(textValue()) 45 | isArray -> ListSourceNode( 46 | mutableListOf().apply { 47 | elements().forEach { 48 | add(it.toTree()) 49 | } 50 | } 51 | ) 52 | isObject -> ContainerNode( 53 | mutableMapOf().apply { 54 | for ((key, value) in fields()) { 55 | put(key, value.toTree()) 56 | } 57 | } 58 | ) 59 | isMissingNode -> ContainerNode(mutableMapOf()) 60 | else -> throw NotImplementedError() 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/source/base/KVSourceSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.base 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.source.asValue 22 | import com.uchuhimo.konf.toPath 23 | import org.jetbrains.spek.api.dsl.given 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | import org.jetbrains.spek.subject.SubjectSpek 27 | import kotlin.test.assertFalse 28 | import kotlin.test.assertNull 29 | import kotlin.test.assertTrue 30 | 31 | object KVSourceSpec : SubjectSpek({ 32 | subject { KVSource(map = mapOf("1" to 1)) } 33 | 34 | given("a KV source") { 35 | on("get the underlying map") { 36 | it("should return the specified map") { 37 | assertThat(subject.map, equalTo(mapOf("1" to 1 as Any))) 38 | } 39 | } 40 | on("get an existed key") { 41 | it("should contain the key") { 42 | assertTrue("1".toPath() in subject) 43 | } 44 | it("should contain the corresponding value") { 45 | assertThat(subject.getOrNull("1".toPath())?.asValue(), equalTo(1)) 46 | } 47 | } 48 | on("get an non-existed key") { 49 | it("should not contain the key") { 50 | assertFalse("2".toPath() in subject) 51 | } 52 | it("should not contain the corresponding value") { 53 | assertNull(subject.getOrNull("2".toPath())) 54 | } 55 | } 56 | } 57 | }) 58 | -------------------------------------------------------------------------------- /konf-git/src/test/kotlin/com/uchuhimo/konf/source/DefaultGitProviderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.tempDirectory 22 | import org.eclipse.jgit.api.Git 23 | import org.jetbrains.spek.api.dsl.given 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | import org.jetbrains.spek.subject.SubjectSpek 27 | import java.nio.file.Paths 28 | 29 | object DefaultGitProviderSpec : SubjectSpek({ 30 | subject { Source.from } 31 | 32 | val item = DefaultLoadersConfig.type 33 | 34 | given("a provider") { 35 | on("provider source from git repository") { 36 | tempDirectory().let { dir -> 37 | Git.init().apply { 38 | setDirectory(dir) 39 | }.call().use { git -> 40 | Paths.get(dir.path, "source.properties").toFile().writeText(propertiesContent) 41 | git.add().apply { 42 | addFilepattern("source.properties") 43 | }.call() 44 | git.commit().apply { 45 | message = "init commit" 46 | }.call() 47 | } 48 | val repo = dir.toURI() 49 | val config = subject.git(repo.toString(), "source.properties").toConfig() 50 | it("should provide as auto-detected file format") { 51 | assertThat(config[item], equalTo("properties")) 52 | } 53 | } 54 | } 55 | } 56 | }) 57 | -------------------------------------------------------------------------------- /konf-yaml/src/test/kotlin/com/uchuhimo/konf/source/yaml/YamlWriterSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.yaml 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.ConfigSpec 23 | import com.uchuhimo.konf.source.Writer 24 | import org.jetbrains.spek.api.dsl.given 25 | import org.jetbrains.spek.api.dsl.it 26 | import org.jetbrains.spek.api.dsl.on 27 | import org.jetbrains.spek.subject.SubjectSpek 28 | import java.io.ByteArrayOutputStream 29 | import java.io.StringWriter 30 | 31 | object YamlWriterSpec : SubjectSpek({ 32 | subject { 33 | val config = Config { 34 | addSpec( 35 | object : ConfigSpec() { 36 | val key by optional("value") 37 | } 38 | ) 39 | } 40 | config.toYaml 41 | } 42 | 43 | given("a writer") { 44 | val expectedString = "key: value" + System.lineSeparator() 45 | on("save to writer") { 46 | val writer = StringWriter() 47 | subject.toWriter(writer) 48 | it("should return a writer which contains content from config") { 49 | assertThat(writer.toString(), equalTo(expectedString)) 50 | } 51 | } 52 | on("save to output stream") { 53 | val outputStream = ByteArrayOutputStream() 54 | subject.toOutputStream(outputStream) 55 | it("should return an output stream which contains content from config") { 56 | assertThat(outputStream.toString(), equalTo(expectedString)) 57 | } 58 | } 59 | } 60 | }) 61 | -------------------------------------------------------------------------------- /konf-xml/src/main/kotlin/com/uchuhimo/konf/source/xml/XmlWriter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.xml 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.source.Writer 21 | import com.uchuhimo.konf.source.base.toFlatMap 22 | import org.dom4j.Document 23 | import org.dom4j.DocumentHelper 24 | import org.dom4j.io.OutputFormat 25 | import org.dom4j.io.XMLWriter 26 | import java.io.OutputStream 27 | 28 | /** 29 | * Writer for XML source. 30 | */ 31 | class XmlWriter(val config: Config) : Writer { 32 | private fun Map.toDocument(): Document { 33 | val document = DocumentHelper.createDocument() 34 | val rootElement = document.addElement("configuration") 35 | for ((key, value) in this) { 36 | val propertyElement = rootElement.addElement("property") 37 | propertyElement.addElement("name").text = key 38 | propertyElement.addElement("value").text = value 39 | } 40 | return document 41 | } 42 | 43 | private val outputFormat = OutputFormat.createPrettyPrint().apply { 44 | lineSeparator = System.lineSeparator() 45 | } 46 | 47 | override fun toWriter(writer: java.io.Writer) { 48 | val xmlWriter = XMLWriter(writer, outputFormat) 49 | xmlWriter.write(config.toFlatMap().toDocument()) 50 | xmlWriter.close() 51 | } 52 | 53 | override fun toOutputStream(outputStream: OutputStream) { 54 | val xmlWriter = XMLWriter(outputStream, outputFormat) 55 | xmlWriter.write(config.toFlatMap().toDocument()) 56 | xmlWriter.close() 57 | } 58 | } 59 | 60 | /** 61 | * Returns writer for XML source. 62 | */ 63 | val Config.toXml: Writer get() = XmlWriter(this) 64 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/base/MapSource.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.base 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.ListNode 21 | import com.uchuhimo.konf.TreeNode 22 | import com.uchuhimo.konf.ValueNode 23 | import com.uchuhimo.konf.notEmptyOr 24 | import com.uchuhimo.konf.source.SourceInfo 25 | import com.uchuhimo.konf.toTree 26 | 27 | /** 28 | * Source from a hierarchical map. 29 | */ 30 | open class MapSource( 31 | val map: Map, 32 | type: String = "", 33 | info: SourceInfo = SourceInfo() 34 | ) : ValueSource(map, type.notEmptyOr("map"), info) 35 | 36 | /** 37 | * Returns a hierarchical map for this config. 38 | * 39 | * The returned map contains all items in this config. 40 | * This map can be loaded into config as [com.uchuhimo.konf.source.base.MapSource] using 41 | * `config.from.map.hierarchical(map)`. 42 | */ 43 | @Suppress("UNCHECKED_CAST") 44 | fun Config.toHierarchicalMap(): Map { 45 | return toTree().toHierarchical() as Map 46 | } 47 | 48 | /** 49 | * Returns a hierarchical value for this tree node. 50 | * 51 | * The returned value contains all items in this tree node. 52 | */ 53 | fun TreeNode.toHierarchical(): Any = withoutPlaceHolder().toHierarchicalInternal() 54 | 55 | private fun TreeNode.toHierarchicalInternal(): Any { 56 | when (this) { 57 | is ValueNode -> return value 58 | is ListNode -> return list.map { it.toHierarchicalInternal() } 59 | else -> return children.mapValues { (_, child) -> child.toHierarchicalInternal() } 60 | } 61 | } 62 | 63 | /** 64 | * Source from an empty map. 65 | */ 66 | class EmptyMapSource : MapSource(emptyMap(), "empty map") 67 | -------------------------------------------------------------------------------- /konf-hocon/src/main/kotlin/com/uchuhimo/konf/source/hocon/HoconSource.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.hocon 18 | 19 | import com.typesafe.config.Config 20 | import com.typesafe.config.ConfigList 21 | import com.typesafe.config.ConfigObject 22 | import com.typesafe.config.ConfigValue 23 | import com.typesafe.config.ConfigValueType 24 | import com.uchuhimo.konf.ContainerNode 25 | import com.uchuhimo.konf.TreeNode 26 | import com.uchuhimo.konf.source.ListSourceNode 27 | import com.uchuhimo.konf.source.NullSourceNode 28 | import com.uchuhimo.konf.source.Source 29 | import com.uchuhimo.konf.source.SourceInfo 30 | import com.uchuhimo.konf.source.ValueSourceNode 31 | 32 | private fun ConfigValue.toTree(): TreeNode { 33 | return when (valueType()!!) { 34 | ConfigValueType.NULL -> NullSourceNode 35 | ConfigValueType.BOOLEAN, ConfigValueType.NUMBER, ConfigValueType.STRING -> ValueSourceNode(unwrapped()) 36 | ConfigValueType.LIST -> ListSourceNode( 37 | mutableListOf().apply { 38 | for (value in (this@toTree as ConfigList)) { 39 | add(value.toTree()) 40 | } 41 | } 42 | ) 43 | ConfigValueType.OBJECT -> ContainerNode( 44 | mutableMapOf().apply { 45 | for ((key, value) in (this@toTree as ConfigObject)) { 46 | put(key, value.toTree()) 47 | } 48 | } 49 | ) 50 | } 51 | } 52 | 53 | /** 54 | * Source from a HOCON value. 55 | */ 56 | class HoconSource( 57 | val value: Config 58 | ) : Source { 59 | override val info: SourceInfo = SourceInfo("type" to "HOCON") 60 | 61 | override val tree: TreeNode = value.root().toTree() 62 | } 63 | -------------------------------------------------------------------------------- /konf-js/src/test/kotlin/com/uchuhimo/konf/source/js/JsWriterSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.js 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.ConfigSpec 23 | import com.uchuhimo.konf.source.Writer 24 | import org.jetbrains.spek.api.dsl.given 25 | import org.jetbrains.spek.api.dsl.it 26 | import org.jetbrains.spek.api.dsl.on 27 | import org.jetbrains.spek.subject.SubjectSpek 28 | import java.io.ByteArrayOutputStream 29 | import java.io.StringWriter 30 | 31 | object JsWriterSpec : SubjectSpek({ 32 | subject { 33 | val config = Config { 34 | addSpec( 35 | object : ConfigSpec() { 36 | val key by optional("value") 37 | } 38 | ) 39 | } 40 | config.toJs 41 | } 42 | 43 | given("a writer") { 44 | val expectedString = 45 | """({ 46 | | key: "value" 47 | |})""".trimMargin().replace("\n", System.lineSeparator()) 48 | on("save to writer") { 49 | val writer = StringWriter() 50 | subject.toWriter(writer) 51 | it("should return a writer which contains content from config") { 52 | assertThat(writer.toString(), equalTo(expectedString)) 53 | } 54 | } 55 | on("save to output stream") { 56 | val outputStream = ByteArrayOutputStream() 57 | subject.toOutputStream(outputStream) 58 | it("should return an output stream which contains content from config") { 59 | assertThat(outputStream.toString(), equalTo(expectedString)) 60 | } 61 | } 62 | } 63 | }) 64 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/MergedMap.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf 18 | 19 | class MergedMap(val fallback: MutableMap, val facade: MutableMap) : MutableMap { 20 | override val size: Int 21 | get() = keys.size 22 | 23 | override fun containsKey(key: K): Boolean { 24 | return facade.containsKey(key) || fallback.containsKey(key) 25 | } 26 | 27 | override fun containsValue(value: V): Boolean { 28 | return facade.containsValue(value) || fallback.containsValue(value) 29 | } 30 | 31 | override fun get(key: K): V? { 32 | return facade[key] ?: fallback[key] 33 | } 34 | 35 | override fun isEmpty(): Boolean { 36 | return facade.isEmpty() && fallback.isEmpty() 37 | } 38 | 39 | override val entries: MutableSet> 40 | get() = keys.map { it to getValue(it) }.toMap(LinkedHashMap()).entries 41 | override val keys: MutableSet 42 | get() = facade.keys.union(fallback.keys).toMutableSet() 43 | override val values: MutableCollection 44 | get() = keys.map { getValue(it) }.toMutableList() 45 | 46 | override fun clear() { 47 | facade.clear() 48 | fallback.clear() 49 | } 50 | 51 | override fun put(key: K, value: V): V? { 52 | return facade.put(key, value) 53 | } 54 | 55 | override fun putAll(from: Map) { 56 | facade.putAll(from) 57 | } 58 | 59 | override fun remove(key: K): V? { 60 | if (key in facade) { 61 | if (key in fallback) { 62 | fallback.remove(key) 63 | } 64 | return facade.remove(key) 65 | } else { 66 | return fallback.remove(key) 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/source/json/JsonWriterSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.json 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.ConfigSpec 23 | import com.uchuhimo.konf.source.Writer 24 | import org.jetbrains.spek.api.dsl.given 25 | import org.jetbrains.spek.api.dsl.it 26 | import org.jetbrains.spek.api.dsl.on 27 | import org.jetbrains.spek.subject.SubjectSpek 28 | import java.io.ByteArrayOutputStream 29 | import java.io.StringWriter 30 | 31 | object JsonWriterSpec : SubjectSpek({ 32 | subject { 33 | val config = Config { 34 | addSpec( 35 | object : ConfigSpec() { 36 | val key by optional("value") 37 | } 38 | ) 39 | } 40 | config.toJson 41 | } 42 | 43 | given("a writer") { 44 | //language=Json 45 | val expectedString = 46 | """ 47 | { 48 | "key" : "value" 49 | } 50 | """.trimIndent().replace("\n", System.lineSeparator()) 51 | on("save to writer") { 52 | val writer = StringWriter() 53 | subject.toWriter(writer) 54 | it("should return a writer which contains content from config") { 55 | assertThat(writer.toString(), equalTo(expectedString)) 56 | } 57 | } 58 | on("save to output stream") { 59 | val outputStream = ByteArrayOutputStream() 60 | subject.toOutputStream(outputStream) 61 | it("should return an output stream which contains content from config") { 62 | assertThat(outputStream.toString(), equalTo(expectedString)) 63 | } 64 | } 65 | } 66 | }) 67 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/SizeInBytesSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.natpryce.hamkrest.throws 22 | import com.uchuhimo.konf.source.ParseException 23 | import org.jetbrains.spek.api.Spek 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | 27 | object SizeInBytesSpec : Spek({ 28 | on("parse valid string") { 29 | it("parse as valid size in bytes") { 30 | assertThat(SizeInBytes.parse("1k").bytes, equalTo(1024L)) 31 | } 32 | } 33 | on("init with negative number") { 34 | it("should throw IllegalArgumentException") { 35 | assertThat({ SizeInBytes(-1L) }, throws()) 36 | } 37 | } 38 | on("parse string without number part") { 39 | it("should throw ParseException") { 40 | assertThat({ SizeInBytes.parse("m") }, throws()) 41 | } 42 | } 43 | on("parse string with float number") { 44 | it("parse and convert from double to long") { 45 | assertThat(SizeInBytes.parse("1.5kB").bytes, equalTo(1500L)) 46 | } 47 | } 48 | on("parse string with invalid unit") { 49 | it("throws ParseException") { 50 | assertThat({ SizeInBytes.parse("1kb") }, throws()) 51 | } 52 | } 53 | on("parse string with invalid number") { 54 | it("throws ParseException") { 55 | assertThat({ SizeInBytes.parse("*1k") }, throws()) 56 | } 57 | } 58 | on("parse number out of range for a 64-bit long") { 59 | it("throws ParseException") { 60 | assertThat({ SizeInBytes.parse("1z") }, throws()) 61 | } 62 | } 63 | }) 64 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/source/base/MapSourceSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.base 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.ValueNode 22 | import com.uchuhimo.konf.source.asValue 23 | import com.uchuhimo.konf.toPath 24 | import org.jetbrains.spek.api.dsl.given 25 | import org.jetbrains.spek.api.dsl.it 26 | import org.jetbrains.spek.api.dsl.on 27 | import org.jetbrains.spek.subject.SubjectSpek 28 | import kotlin.test.assertFalse 29 | import kotlin.test.assertNull 30 | import kotlin.test.assertTrue 31 | 32 | object MapSourceSpec : SubjectSpek({ 33 | subject { MapSource(map = mapOf("1" to 1)) } 34 | 35 | given("a map source") { 36 | on("get the underlying map") { 37 | it("should return the specified map") { 38 | assertThat(subject.map, equalTo(mapOf("1" to 1 as Any))) 39 | } 40 | } 41 | on("cast to map") { 42 | it("should succeed") { 43 | val map = subject.tree.children 44 | assertThat((map["1"] as ValueNode).value, equalTo(1 as Any)) 45 | } 46 | } 47 | on("get an existed key") { 48 | it("should contain the key") { 49 | assertTrue("1".toPath() in subject) 50 | } 51 | it("should contain the corresponding value") { 52 | assertThat(subject.getOrNull("1".toPath())?.asValue(), equalTo(1)) 53 | } 54 | } 55 | on("get an non-existed key") { 56 | it("should not contain the key") { 57 | assertFalse("2".toPath() in subject) 58 | } 59 | it("should not contain the corresponding value") { 60 | assertNull(subject.getOrNull("2".toPath())) 61 | } 62 | } 63 | } 64 | }) 65 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/deserializer/JSR310Deserializer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.deserializer 18 | 19 | import com.fasterxml.jackson.core.JsonParser 20 | import com.fasterxml.jackson.core.JsonTokenId 21 | import com.fasterxml.jackson.databind.DeserializationContext 22 | import com.fasterxml.jackson.databind.deser.std.StdDeserializer 23 | import com.fasterxml.jackson.databind.exc.MismatchedInputException 24 | import java.time.format.DateTimeParseException 25 | 26 | /** 27 | * Base class of deserializers for datetime classes in JSR310. 28 | * 29 | * @param T type of datetime value 30 | */ 31 | abstract class JSR310Deserializer(clazz: Class) : StdDeserializer(clazz) { 32 | /** 33 | * Parses from a string to datetime value. 34 | * 35 | * @param string input string 36 | * @return datetime value 37 | * @throws DateTimeParseException 38 | */ 39 | abstract fun parse(string: String): T 40 | 41 | final override fun deserialize(parser: JsonParser, context: DeserializationContext): T? { 42 | when (parser.currentTokenId()) { 43 | JsonTokenId.ID_STRING -> { 44 | val string = parser.text.trim { it <= ' ' } 45 | if (string.isEmpty()) { 46 | return null 47 | } 48 | try { 49 | return parse(string) 50 | } catch (exception: DateTimeParseException) { 51 | throw context.weirdStringException(string, handledType(), exception.message).apply { 52 | initCause(exception) 53 | } 54 | } 55 | } 56 | } 57 | throw MismatchedInputException.from( 58 | parser, 59 | handledType(), 60 | "Unexpected token (${parser.currentToken}), expected string for ${handledType().name} value" 61 | ) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /konf-hocon/src/test/kotlin/com/uchuhimo/konf/source/hocon/HoconWriterSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.hocon 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.ConfigSpec 23 | import com.uchuhimo.konf.source.Writer 24 | import org.jetbrains.spek.api.dsl.given 25 | import org.jetbrains.spek.api.dsl.it 26 | import org.jetbrains.spek.api.dsl.on 27 | import org.jetbrains.spek.subject.SubjectSpek 28 | import java.io.ByteArrayOutputStream 29 | import java.io.StringWriter 30 | 31 | object HoconWriterSpec : SubjectSpek({ 32 | subject { 33 | val config = Config { 34 | addSpec( 35 | object : ConfigSpec() { 36 | val key by optional("value") 37 | } 38 | ) 39 | } 40 | config.toHocon 41 | } 42 | 43 | given("a writer") { 44 | val expectedString = "key=value" + System.lineSeparator() 45 | on("save to string") { 46 | val string = subject.toText() 47 | it("should return a string which contains content from config") { 48 | assertThat(string, equalTo(expectedString)) 49 | } 50 | } 51 | on("save to writer") { 52 | val writer = StringWriter() 53 | subject.toWriter(writer) 54 | it("should return a writer which contains content from config") { 55 | assertThat(writer.toString(), equalTo(expectedString)) 56 | } 57 | } 58 | on("save to output stream") { 59 | val outputStream = ByteArrayOutputStream() 60 | subject.toOutputStream(outputStream) 61 | it("should return an output stream which contains content from config") { 62 | assertThat(outputStream.toString(), equalTo(expectedString)) 63 | } 64 | } 65 | } 66 | }) 67 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/deserializer/StringDeserializer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.deserializer 18 | 19 | import com.fasterxml.jackson.core.JsonParser 20 | import com.fasterxml.jackson.core.JsonToken 21 | import com.fasterxml.jackson.databind.DeserializationContext 22 | import com.fasterxml.jackson.databind.DeserializationFeature 23 | import com.fasterxml.jackson.databind.deser.std.StringDeserializer as JacksonStringDeserializer 24 | 25 | object StringDeserializer : JacksonStringDeserializer() { 26 | override fun _deserializeFromArray(p: JsonParser, ctxt: DeserializationContext): String? { 27 | val t = p.nextToken() 28 | if (t == JsonToken.END_ARRAY && ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT)) { 29 | return getNullValue(ctxt) 30 | } 31 | if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { 32 | val parsed = deserialize(p, ctxt) 33 | val token = p.nextToken() 34 | if (token != JsonToken.END_ARRAY) { 35 | return parsed + "," + deserializeFromRestOfArray(token, p, ctxt) 36 | } 37 | return parsed 38 | } 39 | return deserializeFromRestOfArray(t, p, ctxt) 40 | } 41 | 42 | private fun deserializeFromRestOfArray( 43 | token: JsonToken, 44 | p: JsonParser, 45 | ctxt: DeserializationContext 46 | ): String { 47 | var t = token 48 | val sb = StringBuilder(64) 49 | while (t != JsonToken.END_ARRAY) { 50 | val str = if (t == JsonToken.VALUE_STRING) { 51 | p.text 52 | } else { 53 | _parseString(p, ctxt) 54 | } 55 | if (sb.isEmpty()) { 56 | sb.append(str) 57 | } else { 58 | sb.append(',').append(str) 59 | } 60 | t = p.nextToken() 61 | } 62 | return sb.toString() 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /konf-yaml/src/main/kotlin/com/uchuhimo/konf/source/yaml/YamlProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.yaml 18 | 19 | import com.uchuhimo.konf.annotation.JavaApi 20 | import com.uchuhimo.konf.source.Provider 21 | import com.uchuhimo.konf.source.RegisterExtension 22 | import com.uchuhimo.konf.source.Source 23 | import com.uchuhimo.konf.source.asSource 24 | import org.yaml.snakeyaml.Yaml 25 | import org.yaml.snakeyaml.constructor.AbstractConstruct 26 | import org.yaml.snakeyaml.constructor.SafeConstructor 27 | import org.yaml.snakeyaml.nodes.Node 28 | import org.yaml.snakeyaml.nodes.ScalarNode 29 | import org.yaml.snakeyaml.nodes.Tag 30 | import java.io.InputStream 31 | import java.io.Reader 32 | 33 | /** 34 | * Provider for YAML source. 35 | */ 36 | @RegisterExtension(["yml", "yaml"]) 37 | object YamlProvider : Provider { 38 | override fun reader(reader: Reader): Source { 39 | val yaml = Yaml(YamlConstructor()) 40 | val value = yaml.load(reader) 41 | if (value == "null") { 42 | return mapOf().asSource("YAML") 43 | } else { 44 | return value.asSource("YAML") 45 | } 46 | } 47 | 48 | override fun inputStream(inputStream: InputStream): Source { 49 | val yaml = Yaml(YamlConstructor()) 50 | val value = yaml.load(inputStream) 51 | if (value == "null") { 52 | return mapOf().asSource("YAML") 53 | } else { 54 | return value.asSource("YAML") 55 | } 56 | } 57 | 58 | @JavaApi 59 | @JvmStatic 60 | fun get() = this 61 | } 62 | 63 | private class YamlConstructor : SafeConstructor() { 64 | init { 65 | yamlConstructors[Tag.NULL] = object : AbstractConstruct() { 66 | override fun construct(node: Node?): Any? { 67 | if (node != null) { 68 | constructScalar(node as ScalarNode) 69 | } 70 | return "null" 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /konf-toml/src/test/kotlin/com/uchuhimo/konf/source/toml/TomlWriterSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.toml 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.ConfigSpec 23 | import com.uchuhimo.konf.source.Writer 24 | import org.jetbrains.spek.api.dsl.given 25 | import org.jetbrains.spek.api.dsl.it 26 | import org.jetbrains.spek.api.dsl.on 27 | import org.jetbrains.spek.subject.SubjectSpek 28 | import java.io.ByteArrayOutputStream 29 | import java.io.StringWriter 30 | 31 | object TomlWriterSpec : SubjectSpek({ 32 | subject { 33 | val config = Config { 34 | addSpec( 35 | object : ConfigSpec() { 36 | val key by optional("value") 37 | } 38 | ) 39 | } 40 | config.toToml 41 | } 42 | 43 | given("a writer") { 44 | val expectedString = 45 | """key = "value" 46 | |""".trimMargin().replace("\n", System.lineSeparator()) 47 | on("save to string") { 48 | val string = subject.toText() 49 | it("should return a string which contains content from config") { 50 | assertThat(string, equalTo(expectedString)) 51 | } 52 | } 53 | on("save to writer") { 54 | val writer = StringWriter() 55 | subject.toWriter(writer) 56 | it("should return a writer which contains content from config") { 57 | assertThat(writer.toString(), equalTo(expectedString)) 58 | } 59 | } 60 | on("save to output stream") { 61 | val outputStream = ByteArrayOutputStream() 62 | subject.toOutputStream(outputStream) 63 | it("should return an output stream which contains content from config") { 64 | assertThat(outputStream.toString(), equalTo(expectedString)) 65 | } 66 | } 67 | } 68 | }) 69 | -------------------------------------------------------------------------------- /konf-core/src/main/kotlin/com/uchuhimo/konf/source/properties/PropertiesWriter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.properties 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.source.Writer 21 | import com.uchuhimo.konf.source.base.toFlatMap 22 | import java.io.FilterOutputStream 23 | import java.io.OutputStream 24 | import java.util.Properties 25 | 26 | /** 27 | * Writer for properties source. 28 | */ 29 | class PropertiesWriter(val config: Config) : Writer { 30 | override fun toWriter(writer: java.io.Writer) { 31 | NoCommentProperties().apply { putAll(config.toFlatMap()) }.store(writer, null) 32 | } 33 | 34 | override fun toOutputStream(outputStream: OutputStream) { 35 | NoCommentProperties().apply { putAll(config.toFlatMap()) }.store(outputStream, null) 36 | } 37 | } 38 | 39 | private class NoCommentProperties : Properties() { 40 | private class StripFirstLineStream(out: OutputStream) : FilterOutputStream(out) { 41 | private var firstLineSeen = false 42 | 43 | override fun write(b: Int) { 44 | if (firstLineSeen) { 45 | super.write(b) 46 | } else if (b == '\n'.toInt()) { 47 | firstLineSeen = true 48 | } 49 | } 50 | } 51 | 52 | private class StripFirstLineWriter(writer: java.io.Writer) : java.io.FilterWriter(writer) { 53 | override fun write(cbuf: CharArray, off: Int, len: Int) { 54 | val offset = cbuf.indexOfFirst { it == '\n' } 55 | super.write(cbuf, offset + 1, len - offset - 1) 56 | } 57 | } 58 | 59 | override fun store(out: OutputStream, comments: String?) { 60 | super.store(StripFirstLineStream(out), null) 61 | } 62 | 63 | override fun store(writer: java.io.Writer, comments: String?) { 64 | super.store(StripFirstLineWriter(writer), null) 65 | } 66 | } 67 | 68 | /** 69 | * Returns writer for properties source. 70 | */ 71 | val Config.toProperties: Writer get() = PropertiesWriter(this) 72 | -------------------------------------------------------------------------------- /konf-xml/src/test/kotlin/com/uchuhimo/konf/source/xml/XmlWriterSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.xml 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.ConfigSpec 23 | import com.uchuhimo.konf.source.Writer 24 | import org.jetbrains.spek.api.dsl.given 25 | import org.jetbrains.spek.api.dsl.it 26 | import org.jetbrains.spek.api.dsl.on 27 | import org.jetbrains.spek.subject.SubjectSpek 28 | import java.io.ByteArrayOutputStream 29 | import java.io.StringWriter 30 | 31 | object XmlWriterSpec : SubjectSpek({ 32 | subject { 33 | val config = Config { 34 | addSpec( 35 | object : ConfigSpec() { 36 | val key by optional("value") 37 | } 38 | ) 39 | } 40 | config.toXml 41 | } 42 | 43 | given("a writer") { 44 | val expectedString = 45 | """ 46 | | 47 | | 48 | | 49 | | 50 | | key 51 | | value 52 | | 53 | | 54 | |""".trimMargin().replace("\n", System.lineSeparator()) 55 | on("save to writer") { 56 | val writer = StringWriter() 57 | subject.toWriter(writer) 58 | it("should return a writer which contains content from config") { 59 | assertThat(writer.toString(), equalTo(expectedString)) 60 | } 61 | } 62 | on("save to output stream") { 63 | val outputStream = ByteArrayOutputStream() 64 | subject.toOutputStream(outputStream) 65 | it("should return an output stream which contains content from config") { 66 | assertThat(outputStream.toString(), equalTo(expectedString)) 67 | } 68 | } 69 | } 70 | }) 71 | -------------------------------------------------------------------------------- /konf-core/src/testFixtures/kotlin/com/uchuhimo/konf/source/base/FlatSourceLoadBaseSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.base 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.source.SourceLoadBaseSpec 23 | import org.jetbrains.spek.api.dsl.given 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | import org.jetbrains.spek.subject.SubjectSpek 27 | import org.jetbrains.spek.subject.itBehavesLike 28 | import java.util.Arrays 29 | import kotlin.test.assertTrue 30 | 31 | object FlatSourceLoadBaseSpec : SubjectSpek({ 32 | itBehavesLike(SourceLoadBaseSpec) 33 | 34 | given("a flat source") { 35 | on("load the source into config") { 36 | it("should contain every value specified in the source") { 37 | val classForLoad = ClassForLoad( 38 | stringWithComma = "string,with,comma", 39 | emptyList = listOf(), 40 | emptySet = setOf(), 41 | emptyArray = intArrayOf(), 42 | emptyObjectArray = arrayOf(), 43 | singleElementList = listOf(1), 44 | multipleElementsList = listOf(1, 2) 45 | ) 46 | assertThat(subject[FlatConfigForLoad.emptyList], equalTo(listOf())) 47 | assertThat(subject[FlatConfigForLoad.emptySet], equalTo(setOf())) 48 | assertTrue(Arrays.equals(subject[FlatConfigForLoad.emptyArray], intArrayOf())) 49 | assertTrue(Arrays.equals(subject[FlatConfigForLoad.emptyObjectArray], arrayOf())) 50 | assertThat(subject[FlatConfigForLoad.singleElementList], equalTo(listOf(1))) 51 | assertThat(subject[FlatConfigForLoad.multipleElementsList], equalTo(listOf(1, 2))) 52 | assertThat( 53 | subject[FlatConfigForLoad.flatClass].stringWithComma, 54 | equalTo(classForLoad.stringWithComma) 55 | ) 56 | } 57 | } 58 | } 59 | }) 60 | -------------------------------------------------------------------------------- /konf-all/src/snippet/kotlin/com/uchuhimo/konf/snippet/Config.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.snippet 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.ConfigSpec 21 | 22 | fun main(args: Array) { 23 | val config = Config() 24 | config.addSpec(Server) 25 | run { 26 | val host = config[Server.host] 27 | } 28 | run { 29 | val host = config.get("server.host") 30 | } 31 | run { 32 | val host = config("server.host") 33 | } 34 | config.contains(Server.host) 35 | // or 36 | Server.host in config 37 | config.contains("server.host") 38 | // or 39 | "server.host" in config 40 | config[Server.tcpPort] = 80 41 | config["server.tcpPort"] = 80 42 | config.containsRequired() 43 | config.validateRequired() 44 | config.unset(Server.tcpPort) 45 | config.unset("server.tcpPort") 46 | val basePort by ConfigSpec("server").required() 47 | config.lazySet(Server.tcpPort) { it[basePort] + 1 } 48 | config.lazySet("server.tcpPort") { it[basePort] + 1 } 49 | run { 50 | val handler = Server.host.onSet { value -> println("the host has changed to $value") } 51 | handler.cancel() 52 | } 53 | run { 54 | val handler = Server.host.beforeSet { config, value -> println("the host will change to $value") } 55 | handler.cancel() 56 | } 57 | run { 58 | val handler = config.beforeSet { item, value -> println("${item.name} will change to $value") } 59 | handler.cancel() 60 | } 61 | run { 62 | val handler = Server.host.afterSet { config, value -> println("the host has changed to $value") } 63 | handler.cancel() 64 | } 65 | run { 66 | val handler = config.afterSet { item, value -> println("${item.name} has changed to $value") } 67 | handler.cancel() 68 | } 69 | run { 70 | var port by config.property(Server.tcpPort) 71 | port = 9090 72 | check(port == 9090) 73 | } 74 | run { 75 | val port by config.property(Server.tcpPort) 76 | check(port == 9090) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /konf-yaml/src/test/kotlin/com/uchuhimo/konf/source/yaml/YamlProviderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.yaml 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.source.asValue 22 | import com.uchuhimo.konf.tempFileOf 23 | import org.jetbrains.spek.api.dsl.given 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | import org.jetbrains.spek.subject.SubjectSpek 27 | import org.jetbrains.spek.subject.itBehavesLike 28 | 29 | object YamlProviderSpec : SubjectSpek({ 30 | subject { YamlProvider } 31 | 32 | given("a YAML provider") { 33 | on("create source from reader") { 34 | val source = subject.reader("type: reader".reader()) 35 | it("should have correct type") { 36 | assertThat(source.info["type"], equalTo("YAML")) 37 | } 38 | it("should return a source which contains value from reader") { 39 | assertThat(source["type"].asValue(), equalTo("reader")) 40 | } 41 | } 42 | on("create source from input stream") { 43 | val source = subject.inputStream( 44 | tempFileOf("type: inputStream").inputStream() 45 | ) 46 | it("should have correct type") { 47 | assertThat(source.info["type"], equalTo("YAML")) 48 | } 49 | it("should return a source which contains value from input stream") { 50 | assertThat(source["type"].asValue(), equalTo("inputStream")) 51 | } 52 | } 53 | on("create source from an empty file") { 54 | val file = tempFileOf("") 55 | it("should return an empty source") { 56 | assertThat( 57 | subject.file(file).tree.children, 58 | equalTo(mutableMapOf()) 59 | ) 60 | } 61 | } 62 | } 63 | }) 64 | 65 | object YamlProviderInJavaSpec : SubjectSpek({ 66 | subject { YamlProvider.get() } 67 | 68 | itBehavesLike(YamlProviderSpec) 69 | }) 70 | -------------------------------------------------------------------------------- /konf-js/src/test/kotlin/com/uchuhimo/konf/source/js/JsProviderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.js 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.source.asValue 22 | import com.uchuhimo.konf.tempFileOf 23 | import org.jetbrains.spek.api.dsl.given 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | import org.jetbrains.spek.subject.SubjectSpek 27 | import org.jetbrains.spek.subject.itBehavesLike 28 | 29 | object JsProviderSpec : SubjectSpek({ 30 | subject { JsProvider } 31 | 32 | given("a JavaScript provider") { 33 | on("create source from reader") { 34 | val source = subject.reader("({type: 'reader'})".reader()) 35 | it("should have correct type") { 36 | assertThat(source.info["type"], equalTo("JavaScript")) 37 | } 38 | it("should return a source which contains value from reader") { 39 | assertThat(source["type"].asValue(), equalTo("reader")) 40 | } 41 | } 42 | on("create source from input stream") { 43 | val source = subject.inputStream( 44 | tempFileOf("({type: 'inputStream'})").inputStream() 45 | ) 46 | it("should have correct type") { 47 | assertThat(source.info["type"], equalTo("JavaScript")) 48 | } 49 | it("should return a source which contains value from input stream") { 50 | assertThat(source["type"].asValue(), equalTo("inputStream")) 51 | } 52 | } 53 | on("create source from an empty file") { 54 | val file = tempFileOf("({})") 55 | it("should return an empty source") { 56 | assertThat( 57 | subject.file(file).tree.children, 58 | equalTo(mutableMapOf()) 59 | ) 60 | } 61 | } 62 | } 63 | }) 64 | 65 | object JsProviderInJavaSpec : SubjectSpek({ 66 | subject { JsProvider.get() } 67 | 68 | itBehavesLike(JsProviderSpec) 69 | }) 70 | -------------------------------------------------------------------------------- /konf-toml/src/test/kotlin/com/uchuhimo/konf/source/toml/TomlProviderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.toml 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.source.asValue 22 | import com.uchuhimo.konf.tempFileOf 23 | import org.jetbrains.spek.api.dsl.given 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | import org.jetbrains.spek.subject.SubjectSpek 27 | import org.jetbrains.spek.subject.itBehavesLike 28 | 29 | object TomlProviderSpec : SubjectSpek({ 30 | subject { TomlProvider } 31 | 32 | given("a TOML provider") { 33 | on("create source from reader") { 34 | val source = subject.reader("type = \"reader\"".reader()) 35 | it("should have correct type") { 36 | assertThat(source.info["type"], equalTo("TOML")) 37 | } 38 | it("should return a source which contains value from reader") { 39 | assertThat(source["type"].asValue(), equalTo("reader")) 40 | } 41 | } 42 | on("create source from input stream") { 43 | val source = subject.inputStream( 44 | tempFileOf("type = \"inputStream\"").inputStream() 45 | ) 46 | it("should have correct type") { 47 | assertThat(source.info["type"], equalTo("TOML")) 48 | } 49 | it("should return a source which contains value from input stream") { 50 | assertThat(source["type"].asValue(), equalTo("inputStream")) 51 | } 52 | } 53 | on("create source from an empty file") { 54 | val file = tempFileOf("") 55 | it("should return an empty source") { 56 | assertThat( 57 | subject.file(file).tree.children, 58 | equalTo(mutableMapOf()) 59 | ) 60 | } 61 | } 62 | } 63 | }) 64 | 65 | object TomlProviderInJavaSpec : SubjectSpek({ 66 | subject { TomlProvider.get() } 67 | 68 | itBehavesLike(TomlProviderSpec) 69 | }) 70 | -------------------------------------------------------------------------------- /konf-hocon/src/test/kotlin/com/uchuhimo/konf/source/hocon/HoconProviderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.hocon 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.source.asValue 22 | import com.uchuhimo.konf.tempFileOf 23 | import org.jetbrains.spek.api.dsl.given 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | import org.jetbrains.spek.subject.SubjectSpek 27 | import org.jetbrains.spek.subject.itBehavesLike 28 | 29 | object HoconProviderSpec : SubjectSpek({ 30 | subject { HoconProvider } 31 | 32 | given("a HOCON provider") { 33 | on("create source from reader") { 34 | val source = subject.reader("type = reader".reader()) 35 | it("should have correct type") { 36 | assertThat(source.info["type"], equalTo("HOCON")) 37 | } 38 | it("should return a source which contains value from reader") { 39 | assertThat(source["type"].asValue(), equalTo("reader")) 40 | } 41 | } 42 | on("create source from input stream") { 43 | val source = subject.inputStream( 44 | tempFileOf("type = inputStream").inputStream() 45 | ) 46 | it("should have correct type") { 47 | assertThat(source.info["type"], equalTo("HOCON")) 48 | } 49 | it("should return a source which contains value from input stream") { 50 | assertThat(source["type"].asValue(), equalTo("inputStream")) 51 | } 52 | } 53 | on("create source from an empty file") { 54 | val file = tempFileOf("") 55 | it("should return an empty source") { 56 | assertThat( 57 | subject.file(file).tree.children, 58 | equalTo(mutableMapOf()) 59 | ) 60 | } 61 | } 62 | } 63 | }) 64 | 65 | object HoconProviderInJavaSpec : SubjectSpek({ 66 | subject { HoconProvider.get() } 67 | 68 | itBehavesLike(HoconProviderSpec) 69 | }) 70 | -------------------------------------------------------------------------------- /konf-toml/src/test/resources/source/source.toml: -------------------------------------------------------------------------------- 1 | [level1.level2] 2 | empty = "null" 3 | literalEmpty = "null" 4 | present = 1 5 | 6 | boolean = false 7 | 8 | int = 1 9 | short = 2 10 | byte = 3 11 | bigInteger = 4 12 | long = 4 13 | 14 | double = 1.5 15 | float = -1.5 16 | bigDecimal = 1.5 17 | 18 | char = "a" 19 | 20 | string = "string" 21 | offsetTime = "10:15:30+01:00" 22 | offsetDateTime = "2007-12-03T10:15:30+01:00" 23 | zonedDateTime = "2007-12-03T10:15:30+01:00[Europe/Paris]" 24 | localDate = "2007-12-03" 25 | localTime = "10:15:30" 26 | localDateTime = "2007-12-03T10:15:30" 27 | date = 2007-12-03T10:15:30Z 28 | year = "2007" 29 | yearMonth = "2007-12" 30 | instant = 2007-12-03T10:15:30.00Z 31 | duration = "P2DT3H4M" 32 | simpleDuration = "200millis" 33 | size = "10k" 34 | 35 | enum = "LABEL2" 36 | 37 | list = [1, 2, 3] 38 | mutableList = [1, 2, 3] 39 | listOfList = [[1, 2], [3, 4]] 40 | set = [1, 2, 1] 41 | sortedSet = [2, 1, 1, 3] 42 | 43 | map = { a = 1, b = 2, c = 3 } 44 | intMap = { 1 = "a", 2 = "b", 3 = "c" } 45 | sortedMap = { c = 3, b = 2, a = 1 } 46 | 47 | nested = [[[{ a = 1 }]]] 48 | 49 | [[level1.level2.listOfMap]] 50 | a = 1 51 | b = 2 52 | 53 | [[level1.level2.listOfMap]] 54 | a = 3 55 | b = 4 56 | 57 | [level1.level2.array] 58 | boolean = [true, false] 59 | byte = [1, 2, 3] 60 | short = [1, 2, 3] 61 | int = [1, 2, 3] 62 | long = [4, 5, 6] 63 | float = [-1.0, 0.0, 1.0] 64 | double = [-1.0, 0.0, 1.0] 65 | char = ["a", "b", "c"] 66 | 67 | [level1.level2.array.object] 68 | boolean = [true, false] 69 | int = [1, 2, 3] 70 | string = ["one", "two", "three"] 71 | enum = ["LABEL1", "LABEL2", "LABEL3"] 72 | 73 | [level1.level2.pair] 74 | first = 1 75 | second = 2 76 | 77 | [level1.level2.clazz] 78 | empty = "null" 79 | literalEmpty = "null" 80 | present = 1 81 | 82 | boolean = false 83 | 84 | int = 1 85 | short = 2 86 | byte = 3 87 | bigInteger = 4 88 | long = 4 89 | 90 | double = 1.5 91 | float = -1.5 92 | bigDecimal = 1.5 93 | 94 | char = "a" 95 | 96 | string = "string" 97 | offsetTime = "10:15:30+01:00" 98 | offsetDateTime = "2007-12-03T10:15:30+01:00" 99 | zonedDateTime = "2007-12-03T10:15:30+01:00[Europe/Paris]" 100 | localDate = "2007-12-03" 101 | localTime = "10:15:30" 102 | localDateTime = "2007-12-03T10:15:30" 103 | date = 2007-12-03T10:15:30Z 104 | year = "2007" 105 | yearMonth = "2007-12" 106 | instant = 2007-12-03T10:15:30.00Z 107 | duration = "P2DT3H4M" 108 | simpleDuration = "200millis" 109 | size = "10k" 110 | 111 | enum = "LABEL2" 112 | 113 | booleanArray = [true, false] 114 | 115 | nested = [[[{ a = 1 }]]] 116 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/source/json/JsonProviderSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.json 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.source.asValue 22 | import com.uchuhimo.konf.tempFileOf 23 | import org.jetbrains.spek.api.dsl.given 24 | import org.jetbrains.spek.api.dsl.it 25 | import org.jetbrains.spek.api.dsl.on 26 | import org.jetbrains.spek.subject.SubjectSpek 27 | import org.jetbrains.spek.subject.itBehavesLike 28 | 29 | object JsonProviderSpec : SubjectSpek({ 30 | subject { JsonProvider } 31 | 32 | given("a JSON provider") { 33 | on("create source from reader") { 34 | //language=Json 35 | val source = subject.reader("""{ "type": "reader" }""".reader()) 36 | it("should have correct type") { 37 | assertThat(source.info["type"], equalTo("JSON")) 38 | } 39 | it("should return a source which contains value from reader") { 40 | assertThat(source["type"].asValue(), equalTo("reader")) 41 | } 42 | } 43 | on("create source from input stream") { 44 | //language=Json 45 | val source = subject.inputStream(tempFileOf("""{ "type": "inputStream" }""").inputStream()) 46 | it("should have correct type") { 47 | assertThat(source.info["type"], equalTo("JSON")) 48 | } 49 | it("should return a source which contains value from input stream") { 50 | assertThat(source["type"].asValue(), equalTo("inputStream")) 51 | } 52 | } 53 | on("create source from an empty file") { 54 | val file = tempFileOf("") 55 | it("should return an empty source") { 56 | assertThat( 57 | subject.file(file).tree.children, 58 | equalTo(mutableMapOf()) 59 | ) 60 | } 61 | } 62 | } 63 | }) 64 | 65 | object JsonProviderInJavaSpec : SubjectSpek({ 66 | subject { JsonProvider.get() } 67 | 68 | itBehavesLike(JsonProviderSpec) 69 | }) 70 | -------------------------------------------------------------------------------- /konf-hocon/src/test/resources/source/source.conf: -------------------------------------------------------------------------------- 1 | level1 { 2 | level2 { 3 | empty = "null" 4 | literalEmpty = null 5 | present = 1 6 | 7 | boolean = false 8 | 9 | int = 1 10 | short = 2 11 | byte = 3 12 | bigInteger = 4 13 | long = 4 14 | 15 | double = 1.5 16 | float = -1.5 17 | bigDecimal = 1.5 18 | 19 | char = "a" 20 | 21 | string = string 22 | offsetTime = "10:15:30+01:00" 23 | offsetDateTime = "2007-12-03T10:15:30+01:00" 24 | zonedDateTime = "2007-12-03T10:15:30+01:00[Europe/Paris]" 25 | localDate = 2007-12-03 26 | localTime = "10:15:30" 27 | localDateTime = "2007-12-03T10:15:30" 28 | date = "2007-12-03T10:15:30Z" 29 | year = "2007" 30 | yearMonth = 2007-12 31 | instant = "2007-12-03T10:15:30.00Z" 32 | duration = P2DT3H4M 33 | simpleDuration = 200millis 34 | size = 10k 35 | 36 | enum = LABEL2 37 | 38 | array { 39 | boolean = [true, false] 40 | byte = [1, 2, 3] 41 | short = [1, 2, 3] 42 | int = [1, 2, 3] 43 | long = [4, 5, 6] 44 | float = [-1, 0.0, 1] 45 | double = [-1, 0.0, 1] 46 | char = [a, b, c] 47 | 48 | object { 49 | boolean = [true, false] 50 | int = [1, 2, 3] 51 | string = [one, two, three] 52 | enum = [LABEL1, LABEL2, LABEL3] 53 | } 54 | } 55 | 56 | list = [1, 2, 3] 57 | mutableList = [1, 2, 3] 58 | listOfList = [[1, 2], [3, 4]] 59 | set = [1, 2, 1] 60 | sortedSet = [2, 1, 1, 3] 61 | 62 | map = {a = 1, b = 2, c = 3} 63 | intMap = {1 = a, 2 = b, 3 = c} 64 | sortedMap = {c = 3, b = 2, a = 1} 65 | listOfMap = [ 66 | {a = 1, b = 2} 67 | {a = 3, b = 4} 68 | ] 69 | 70 | nested = [[[{a = 1}]]] 71 | 72 | pair = {first = 1, second = 2} 73 | 74 | clazz = { 75 | empty = "null" 76 | literalEmpty = null 77 | present = 1 78 | boolean = false 79 | int = 1 80 | short = 2 81 | byte = 3 82 | bigInteger = 4 83 | long = 4 84 | double = 1.5 85 | float = -1.5 86 | bigDecimal = 1.5 87 | char = "a" 88 | string = string 89 | offsetTime = "10:15:30+01:00" 90 | offsetDateTime = "2007-12-03T10:15:30+01:00" 91 | zonedDateTime = "2007-12-03T10:15:30+01:00[Europe/Paris]" 92 | localDate = 2007-12-03 93 | localTime = "10:15:30" 94 | localDateTime = "2007-12-03T10:15:30" 95 | date = "2007-12-03T10:15:30Z" 96 | year = "2007" 97 | yearMonth = 2007-12 98 | instant = "2007-12-03T10:15:30.00Z" 99 | duration = P2DT3H4M 100 | simpleDuration = 200millis 101 | size = 10k 102 | enum = LABEL2 103 | booleanArray = [true, false] 104 | nested = [[[{a = 1}]]] 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /konf-yaml/src/test/resources/source/source.yaml: -------------------------------------------------------------------------------- 1 | level1: 2 | level2: 3 | empty: "null" 4 | literalEmpty: null 5 | present: 1 6 | 7 | boolean: false 8 | 9 | int: 1 10 | short: 2 11 | byte: 3 12 | bigInteger: 4 13 | long: 4 14 | 15 | double: 1.5 16 | float: -1.5 17 | bigDecimal: 1.5 18 | 19 | char: "a" 20 | 21 | string: string 22 | offsetTime: 10:15:30+01:00 23 | offsetDateTime: "2007-12-03T10:15:30+01:00" 24 | zonedDateTime: 2007-12-03T10:15:30+01:00[Europe/Paris] 25 | localDate: 2007-12-03 26 | localTime: "10:15:30" 27 | localDateTime: 2007-12-03T10:15:30 28 | date: 2007-12-03T10:15:30Z 29 | year: "2007" 30 | yearMonth: 2007-12 31 | instant: 2007-12-03T10:15:30.00Z 32 | duration: P2DT3H4M 33 | simpleDuration: 200millis 34 | size: 10k 35 | 36 | enum: LABEL2 37 | 38 | array: 39 | boolean: 40 | - true 41 | - false 42 | byte: [1, 2, 3] 43 | short: [1, 2, 3] 44 | int: [1, 2, 3] 45 | long: [4, 5, 6] 46 | float: [-1, 0.0, 1] 47 | double: [-1, 0.0, 1] 48 | char: [a, b, c] 49 | 50 | object: 51 | boolean: [true, false] 52 | int: [1, 2, 3] 53 | string: [one, two, three] 54 | enum: [LABEL1, LABEL2, LABEL3] 55 | 56 | list: [1, 2, 3] 57 | mutableList: [1, 2, 3] 58 | listOfList: 59 | - - 1 60 | - 2 61 | - [3, 4] 62 | set: [1, 2, 1] 63 | sortedSet: [2, 1, 1, 3] 64 | 65 | map: 66 | a: 1 67 | b: 2 68 | c: 3 69 | intMap: 70 | 1: a 71 | 2: b 72 | 3: c 73 | sortedMap: { c: 3, b: 2, a: 1 } 74 | listOfMap: 75 | - a: 1 76 | b: 2 77 | - a: 3 78 | b: 4 79 | 80 | nested: [[[{ a: 1 }]]] 81 | 82 | pair: 83 | first: 1 84 | second: 2 85 | 86 | clazz: 87 | empty: "null" 88 | literalEmpty: null 89 | present: 1 90 | 91 | boolean: false 92 | 93 | int: 1 94 | short: 2 95 | byte: 3 96 | bigInteger: 4 97 | long: 4 98 | 99 | double: 1.5 100 | float: -1.5 101 | bigDecimal: 1.5 102 | 103 | char: "a" 104 | 105 | string: string 106 | offsetTime: 10:15:30+01:00 107 | offsetDateTime: "2007-12-03T10:15:30+01:00" 108 | zonedDateTime: 2007-12-03T10:15:30+01:00[Europe/Paris] 109 | localDate: 2007-12-03 110 | localTime: "10:15:30" 111 | localDateTime: 2007-12-03T10:15:30 112 | date: 2007-12-03T10:15:30Z 113 | year: "2007" 114 | yearMonth: 2007-12 115 | instant: 2007-12-03T10:15:30.00Z 116 | duration: P2DT3H4M 117 | simpleDuration: 200millis 118 | size: 10k 119 | 120 | enum: LABEL2 121 | 122 | booleanArray: 123 | - true 124 | - false 125 | 126 | nested: [[[{ a: 1 }]]] -------------------------------------------------------------------------------- /konf-all/src/snippet/kotlin/com/uchuhimo/konf/snippet/QuickStart.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.snippet 18 | 19 | import com.uchuhimo.konf.Config 20 | import com.uchuhimo.konf.ConfigSpec 21 | import com.uchuhimo.konf.source.Source 22 | import com.uchuhimo.konf.source.toValue 23 | import com.uchuhimo.konf.source.yaml 24 | import com.uchuhimo.konf.toValue 25 | import java.io.File 26 | 27 | object ServerSpec : ConfigSpec() { 28 | val host by optional("0.0.0.0") 29 | val tcpPort by required() 30 | } 31 | 32 | fun main(args: Array) { 33 | val file = File("server.yml") 34 | //language=YAML 35 | file.writeText( 36 | """ 37 | server: 38 | host: 127.0.0.1 39 | tcp_port: 8080 40 | """.trimIndent() 41 | ) 42 | file.deleteOnExit() 43 | val config = Config { addSpec(ServerSpec) } 44 | .from.yaml.file("server.yml") 45 | .from.json.resource("server.json") 46 | .from.env() 47 | .from.systemProperties() 48 | run { 49 | val config = Config { addSpec(ServerSpec) }.withSource( 50 | Source.from.yaml.file("server.yml") + 51 | Source.from.json.resource("server.json") + 52 | Source.from.env() + 53 | Source.from.systemProperties() 54 | ) 55 | } 56 | run { 57 | val config = Config { addSpec(ServerSpec) } 58 | .from.yaml.watchFile("server.yml") 59 | .from.json.resource("server.json") 60 | .from.env() 61 | .from.systemProperties() 62 | } 63 | val server = Server(config[ServerSpec.host], config[ServerSpec.tcpPort]) 64 | server.start() 65 | run { 66 | val server = Config() 67 | .from.yaml.file("server.yml") 68 | .from.json.resource("server.json") 69 | .from.env() 70 | .from.systemProperties() 71 | .at("server") 72 | .toValue() 73 | server.start() 74 | } 75 | run { 76 | val server = ( 77 | Source.from.yaml.file("server.yml") + 78 | Source.from.json.resource("server.json") + 79 | Source.from.env() + 80 | Source.from.systemProperties() 81 | )["server"] 82 | .toValue() 83 | server.start() 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/source/deserializer/DurationDeserializerSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.deserializer 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.ConfigSpec 23 | import com.uchuhimo.konf.source.ObjectMappingException 24 | import com.uchuhimo.konf.source.assertCausedBy 25 | import org.jetbrains.spek.api.Spek 26 | import org.jetbrains.spek.api.dsl.given 27 | import org.jetbrains.spek.api.dsl.it 28 | import org.jetbrains.spek.api.dsl.on 29 | import java.time.Duration 30 | 31 | object DurationDeserializerSpec : Spek({ 32 | val spec = object : ConfigSpec() { 33 | val item by required() 34 | } 35 | val config by memoized { 36 | Config { 37 | addSpec(spec) 38 | } 39 | } 40 | 41 | given("a duration deserializer") { 42 | on("deserialize valid string") { 43 | config.from.map.kv(mapOf("item" to mapOf("duration" to "P2DT3H4M"))).apply { 44 | it("should succeed") { 45 | assertThat( 46 | this@apply[spec.item].duration, 47 | equalTo(Duration.parse("P2DT3H4M")) 48 | ) 49 | } 50 | } 51 | } 52 | on("deserialize empty string") { 53 | it("should throw LoadException caused by ObjectMappingException") { 54 | assertCausedBy { 55 | config.from.map.kv(mapOf("item" to mapOf("duration" to " "))) 56 | } 57 | } 58 | } 59 | on("deserialize value with invalid type") { 60 | it("should throw LoadException caused by ObjectMappingException") { 61 | assertCausedBy { 62 | config.from.map.kv(mapOf("item" to mapOf("duration" to 1))) 63 | } 64 | } 65 | } 66 | on("deserialize value with invalid format") { 67 | it("should throw LoadException caused by ObjectMappingException") { 68 | assertCausedBy { 69 | config.from.map.kv(mapOf("item" to mapOf("duration" to "*1s"))) 70 | } 71 | } 72 | } 73 | } 74 | }) 75 | 76 | private data class DurationWrapper(val duration: Duration) 77 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/source/CustomDeserializerSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source 18 | 19 | import com.fasterxml.jackson.core.JsonParser 20 | import com.fasterxml.jackson.databind.DeserializationContext 21 | import com.fasterxml.jackson.databind.JsonNode 22 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize 23 | import com.fasterxml.jackson.databind.deser.std.StdDeserializer 24 | import com.natpryce.hamkrest.assertion.assertThat 25 | import com.natpryce.hamkrest.equalTo 26 | import com.uchuhimo.konf.Config 27 | import com.uchuhimo.konf.ConfigSpec 28 | import org.jetbrains.spek.api.dsl.given 29 | import org.jetbrains.spek.api.dsl.it 30 | import org.jetbrains.spek.api.dsl.on 31 | import org.jetbrains.spek.subject.SubjectSpek 32 | 33 | @JsonDeserialize(using = SealedClassDeserializer::class) 34 | sealed class SealedClass 35 | 36 | data class VariantA(val int: Int) : SealedClass() 37 | data class VariantB(val double: Double) : SealedClass() 38 | 39 | class SealedClassDeserializer : StdDeserializer(SealedClass::class.java) { 40 | override fun deserialize(p: JsonParser, ctxt: DeserializationContext): SealedClass { 41 | val node: JsonNode = p.codec.readTree(p) 42 | return if (node.has("int")) { 43 | VariantA(node.get("int").asInt()) 44 | } else { 45 | VariantB(node.get("double").asDouble()) 46 | } 47 | } 48 | } 49 | 50 | object CustomDeserializerConfig : ConfigSpec("level1.level2") { 51 | val variantA by required() 52 | val variantB by required() 53 | } 54 | 55 | object CustomDeserializerSpec : SubjectSpek({ 56 | 57 | subject { 58 | Config { 59 | addSpec(CustomDeserializerConfig) 60 | }.from.map.kv(loadContent) 61 | } 62 | given("a source") { 63 | on("load the source into config") { 64 | it("should contain every value specified in the source") { 65 | val variantA = VariantA(1) 66 | val variantB = VariantB(2.0) 67 | assertThat(subject[CustomDeserializerConfig.variantA], equalTo(variantA)) 68 | assertThat(subject[CustomDeserializerConfig.variantB], equalTo(variantB)) 69 | } 70 | } 71 | } 72 | }) 73 | 74 | private val loadContent = mapOf( 75 | "variantA" to mapOf("int" to 1), 76 | "variantB" to mapOf("double" to 2.0) 77 | ).mapKeys { (key, _) -> "level1.level2.$key" } 78 | -------------------------------------------------------------------------------- /konf-core/src/test/kotlin/com/uchuhimo/konf/source/deserializer/OffsetDateTimeDeserializerSpec.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.uchuhimo.konf.source.deserializer 18 | 19 | import com.natpryce.hamkrest.assertion.assertThat 20 | import com.natpryce.hamkrest.equalTo 21 | import com.uchuhimo.konf.Config 22 | import com.uchuhimo.konf.ConfigSpec 23 | import com.uchuhimo.konf.source.ObjectMappingException 24 | import com.uchuhimo.konf.source.assertCausedBy 25 | import org.jetbrains.spek.api.Spek 26 | import org.jetbrains.spek.api.dsl.given 27 | import org.jetbrains.spek.api.dsl.it 28 | import org.jetbrains.spek.api.dsl.on 29 | import java.time.OffsetDateTime 30 | 31 | object OffsetDateTimeDeserializerSpec : Spek({ 32 | val spec = object : ConfigSpec() { 33 | val item by required() 34 | } 35 | val config by memoized { 36 | Config { 37 | addSpec(spec) 38 | } 39 | } 40 | 41 | given("an OffsetDateTime deserializer") { 42 | on("deserialize valid string") { 43 | config.from.map.kv(mapOf("item" to mapOf("offsetDateTime" to "2007-12-03T10:15:30+01:00"))).apply { 44 | it("should succeed") { 45 | assertThat( 46 | this@apply[spec.item].offsetDateTime, 47 | equalTo(OffsetDateTime.parse("2007-12-03T10:15:30+01:00")) 48 | ) 49 | } 50 | } 51 | } 52 | on("deserialize empty string") { 53 | it("should throw LoadException caused by ObjectMappingException") { 54 | assertCausedBy { 55 | config.from.map.kv(mapOf("item" to mapOf("offsetDateTime" to " "))) 56 | } 57 | } 58 | } 59 | on("deserialize value with invalid type") { 60 | it("should throw LoadException caused by ObjectMappingException") { 61 | assertCausedBy { 62 | config.from.map.kv(mapOf("item" to mapOf("offsetDateTime" to 1))) 63 | } 64 | } 65 | } 66 | on("deserialize value with invalid format") { 67 | it("should throw LoadException caused by ObjectMappingException") { 68 | assertCausedBy { 69 | config.from.map.kv(mapOf("item" to mapOf("offsetDateTime" to "2007-12-03T10:15:30"))) 70 | } 71 | } 72 | } 73 | } 74 | }) 75 | 76 | private data class OffsetDateTimeWrapper(val offsetDateTime: OffsetDateTime) 77 | --------------------------------------------------------------------------------