You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@seatunnel.apache.org by ga...@apache.org on 2022/01/08 06:15:26 UTC
[incubator-seatunnel] branch dev updated: [SeaTunnel #904] [config] improve the config module by shade plugin (#906)
This is an automated email from the ASF dual-hosted git repository.
gaoyingju pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-seatunnel.git
The following commit(s) were added to refs/heads/dev by this push:
new 7655ff8 [SeaTunnel #904] [config] improve the config module by shade plugin (#906)
7655ff8 is described below
commit 7655ff8a5f95000074891a7a123e6fd382c5a39d
Author: leo65535 <le...@163.com>
AuthorDate: Sat Jan 8 14:15:20 2022 +0800
[SeaTunnel #904] [config] improve the config module by shade plugin (#906)
---
pom.xml | 21 +-
.../java/org/apache/seatunnel/plugin/Plugin.java | 2 +-
.../apache/seatunnel/flink/FlinkEnvironment.java | 2 +-
.../seatunnel/flink/batch/FlinkBatchExecution.java | 2 +-
.../flink/stream/FlinkStreamExecution.java | 2 +-
.../seatunnel/flink/util/EnvironmentUtil.java | 2 +-
.../apache/seatunnel/flink/util/SchemaUtil.java | 4 +-
.../org/apache/seatunnel/spark/BaseSparkSink.scala | 2 +-
.../apache/seatunnel/spark/BaseSparkSource.scala | 2 +-
.../seatunnel/spark/BaseSparkTransform.scala | 2 +-
.../apache/seatunnel/spark/SparkEnvironment.scala | 2 +-
.../spark/batch/SparkBatchExecution.scala | 2 +-
.../spark/stream/SparkStreamingExecution.scala | 2 +-
.../StructuredStreamingExecution.scala | 2 +-
.../apache/seatunnel/common/PropertiesUtil.java | 2 +-
.../seatunnel/common/config/CheckConfigUtil.java | 2 +-
.../common/config/TypesafeConfigUtils.java | 6 +-
seatunnel-config/HOCON.md | 1625 --------------------
seatunnel-config/README.md | 930 -----------
seatunnel-config/pom.xml | 88 ++
.../typesafe}/config/ConfigParseOptions.java | 42 +-
.../typesafe}/config/impl/ConfigNodePath.java | 10 +-
.../typesafe}/config/impl/ConfigParser.java | 94 +-
.../typesafe}/config/impl/PathParser.java | 50 +-
.../java/org/apache/seatunnel/config/Config.java | 1016 ------------
.../apache/seatunnel/config/ConfigBeanFactory.java | 62 -
.../apache/seatunnel/config/ConfigException.java | 436 ------
.../org/apache/seatunnel/config/ConfigFactory.java | 1016 ------------
.../seatunnel/config/ConfigIncludeContext.java | 67 -
.../apache/seatunnel/config/ConfigIncluder.java | 62 -
.../seatunnel/config/ConfigIncluderClasspath.java | 37 -
.../seatunnel/config/ConfigIncluderFile.java | 39 -
.../apache/seatunnel/config/ConfigIncluderURL.java | 39 -
.../org/apache/seatunnel/config/ConfigList.java | 61 -
.../seatunnel/config/ConfigLoadingStrategy.java | 37 -
.../apache/seatunnel/config/ConfigMemorySize.java | 79 -
.../apache/seatunnel/config/ConfigMergeable.java | 85 -
.../org/apache/seatunnel/config/ConfigObject.java | 143 --
.../org/apache/seatunnel/config/ConfigOrigin.java | 129 --
.../seatunnel/config/ConfigOriginFactory.java | 81 -
.../apache/seatunnel/config/ConfigParseable.java | 59 -
.../seatunnel/config/ConfigRenderOptions.java | 197 ---
.../seatunnel/config/ConfigResolveOptions.java | 188 ---
.../apache/seatunnel/config/ConfigResolver.java | 56 -
.../org/apache/seatunnel/config/ConfigSyntax.java | 49 -
.../org/apache/seatunnel/config/ConfigUtil.java | 92 --
.../org/apache/seatunnel/config/ConfigValue.java | 133 --
.../seatunnel/config/ConfigValueFactory.java | 165 --
.../apache/seatunnel/config/ConfigValueType.java | 26 -
.../config/DefaultConfigLoadingStrategy.java | 82 -
.../java/org/apache/seatunnel/config/Optional.java | 31 -
.../seatunnel/config/impl/AbstractConfigNode.java | 46 -
.../config/impl/AbstractConfigNodeValue.java | 25 -
.../config/impl/AbstractConfigObject.java | 233 ---
.../seatunnel/config/impl/AbstractConfigValue.java | 425 -----
.../seatunnel/config/impl/ConfigBeanImpl.java | 342 ----
.../seatunnel/config/impl/ConfigBoolean.java | 61 -
.../seatunnel/config/impl/ConfigConcatenation.java | 311 ----
.../seatunnel/config/impl/ConfigDelayedMerge.java | 376 -----
.../config/impl/ConfigDelayedMergeObject.java | 342 ----
.../config/impl/ConfigDocumentParser.java | 719 ---------
.../apache/seatunnel/config/impl/ConfigDouble.java | 75 -
.../apache/seatunnel/config/impl/ConfigImpl.java | 489 ------
.../seatunnel/config/impl/ConfigImplUtil.java | 260 ----
.../seatunnel/config/impl/ConfigIncludeKind.java | 22 -
.../apache/seatunnel/config/impl/ConfigInt.java | 75 -
.../apache/seatunnel/config/impl/ConfigLong.java | 75 -
.../seatunnel/config/impl/ConfigNodeArray.java | 31 -
.../config/impl/ConfigNodeComplexValue.java | 67 -
.../config/impl/ConfigNodeConcatenation.java | 31 -
.../seatunnel/config/impl/ConfigNodeField.java | 92 --
.../seatunnel/config/impl/ConfigNodeInclude.java | 63 -
.../seatunnel/config/impl/ConfigNodeObject.java | 305 ----
.../seatunnel/config/impl/ConfigNodeRoot.java | 85 -
.../config/impl/ConfigNodeSimpleValue.java | 56 -
.../config/impl/ConfigNodeSingleToken.java | 38 -
.../apache/seatunnel/config/impl/ConfigNull.java | 71 -
.../apache/seatunnel/config/impl/ConfigNumber.java | 121 --
.../seatunnel/config/impl/ConfigReference.java | 185 ---
.../apache/seatunnel/config/impl/ConfigString.java | 108 --
.../apache/seatunnel/config/impl/Container.java | 41 -
.../seatunnel/config/impl/DefaultTransformer.java | 145 --
.../apache/seatunnel/config/impl/FromMapMode.java | 22 -
.../apache/seatunnel/config/impl/FullIncluder.java | 28 -
.../org/apache/seatunnel/config/impl/MemoKey.java | 61 -
.../seatunnel/config/impl/MergeableValue.java | 26 -
.../apache/seatunnel/config/impl/OriginType.java | 26 -
.../apache/seatunnel/config/impl/Parseable.java | 933 -----------
.../org/apache/seatunnel/config/impl/Path.java | 250 ---
.../apache/seatunnel/config/impl/PathBuilder.java | 75 -
.../seatunnel/config/impl/PropertiesParser.java | 225 ---
.../config/impl/ReplaceableMergeStack.java | 31 -
.../seatunnel/config/impl/ResolveContext.java | 273 ----
.../apache/seatunnel/config/impl/ResolveMemos.java | 52 -
.../seatunnel/config/impl/ResolveResult.java | 61 -
.../seatunnel/config/impl/ResolveSource.java | 363 -----
.../seatunnel/config/impl/ResolveStatus.java | 41 -
.../config/impl/SerializedConfigValue.java | 556 -------
.../apache/seatunnel/config/impl/SimpleConfig.java | 1174 --------------
.../config/impl/SimpleConfigDocument.java | 86 --
.../seatunnel/config/impl/SimpleConfigList.java | 477 ------
.../seatunnel/config/impl/SimpleConfigObject.java | 695 ---------
.../seatunnel/config/impl/SimpleConfigOrigin.java | 602 --------
.../config/impl/SimpleIncludeContext.java | 66 -
.../seatunnel/config/impl/SimpleIncluder.java | 310 ----
.../config/impl/SubstitutionExpression.java | 65 -
.../org/apache/seatunnel/config/impl/Token.java | 102 --
.../apache/seatunnel/config/impl/TokenType.java | 38 -
.../apache/seatunnel/config/impl/Tokenizer.java | 703 ---------
.../org/apache/seatunnel/config/impl/Tokens.java | 526 -------
.../apache/seatunnel/config/impl/Unmergeable.java | 30 -
.../org/apache/seatunnel/config/impl/package.html | 43 -
.../java/org/apache/seatunnel/config/package.html | 87 --
.../seatunnel/config/parser/ConfigDocument.java | 101 --
.../config/parser/ConfigDocumentFactory.java | 104 --
.../apache/seatunnel/config/parser/ConfigNode.java | 49 -
.../org/apache/seatunnel/config/CompleteTest.java | 47 +
.../org/apache/seatunnel/config/CompleteTests.java | 51 -
.../apache/seatunnel/config/ConfigFactoryTest.java | 69 +
.../seatunnel/config/beanconfig/ArraysConfig.java | 156 --
.../config/beanconfig/BooleansConfig.java | 75 -
.../seatunnel/config/beanconfig/BytesConfig.java | 51 -
.../DifferentFieldNameFromAccessorsConfig.java | 40 -
.../config/beanconfig/DurationsConfig.java | 50 -
.../seatunnel/config/beanconfig/EnumsConfig.java | 83 -
.../config/beanconfig/NotABeanFieldConfig.java | 35 -
.../seatunnel/config/beanconfig/NumbersConfig.java | 76 -
.../seatunnel/config/beanconfig/ObjectsConfig.java | 83 -
.../config/beanconfig/PreferCamelNamesConfig.java | 40 -
.../seatunnel/config/beanconfig/SetsConfig.java | 156 --
.../seatunnel/config/beanconfig/StringsConfig.java | 61 -
.../config/beanconfig/TestBeanConfig.java | 31 -
.../beanconfig/UnsupportedListElementConfig.java | 33 -
.../config/beanconfig/UnsupportedMapKeyConfig.java | 33 -
.../beanconfig/UnsupportedMapValueConfig.java | 33 -
.../config/beanconfig/ValidationBeanConfig.java | 61 -
.../seatunnel/config/beanconfig/ValuesConfig.java | 85 -
.../apache/seatunnel/config/utils/FileUtils.java} | 26 +-
seatunnel-config/src/test/resources/a_1.conf | 16 -
seatunnel-config/src/test/resources/b_2.conf | 16 -
seatunnel-config/src/test/resources/bom.conf | 16 -
seatunnel-config/src/test/resources/cycle.conf | 16 -
.../src/test/resources/equiv01/comments.conf | 60 -
.../src/test/resources/equiv01/equals.conf | 56 -
.../src/test/resources/equiv01/no-commas.conf | 70 -
.../src/test/resources/equiv01/no-root-braces.conf | 55 -
.../src/test/resources/equiv01/no-whitespace.json | 1 -
.../src/test/resources/equiv01/omit-colons.conf | 59 -
.../src/test/resources/equiv01/original.json | 41 -
.../src/test/resources/equiv01/path-keys.conf | 44 -
.../test/resources/equiv01/properties-style.conf | 52 -
.../src/test/resources/equiv01/substitutions.conf | 56 -
.../src/test/resources/equiv01/unquoted.conf | 56 -
.../src/test/resources/equiv02/original.json | 17 -
.../src/test/resources/equiv02/path-keys.conf | 24 -
.../src/test/resources/equiv03/includes.conf | 22 -
.../src/test/resources/equiv03/letters/a.conf | 21 -
.../src/test/resources/equiv03/letters/b.json | 3 -
.../src/test/resources/equiv03/letters/c.conf | 17 -
.../test/resources/equiv03/letters/c.properties | 15 -
.../test/resources/equiv03/letters/numbers/1.conf | 16 -
.../resources/equiv03/letters/numbers/2.properties | 15 -
.../src/test/resources/equiv03/original.json | 15 -
.../src/test/resources/equiv03/root/foo.conf | 16 -
.../resources/equiv04/missing-substitutions.conf | 19 -
.../src/test/resources/equiv04/original.json | 3 -
.../src/test/resources/equiv05/original.json | 16 -
.../src/test/resources/equiv05/triple-quotes.conf | 35 -
.../config.conf} | 57 +-
.../src/test/resources/file-include.conf | 20 -
.../src/test/resources/include-from-list.conf | 20 -
.../src/test/resources/onclasspath.conf | 17 -
.../seatunnel/config/beanconfig/beanconfig01.conf | 146 --
.../src/test/resources/seatunnel/variables.conf | 6 +-
.../src/test/resources/subdir/bar-file.conf | 16 -
.../src/test/resources/subdir/bar.conf | 16 -
.../src/test/resources/subdir/baz.conf | 16 -
.../src/test/resources/subdir/foo.conf | 20 -
seatunnel-config/src/test/resources/test01.conf | 109 --
seatunnel-config/src/test/resources/test01.json | 4 -
.../src/test/resources/test01.properties | 18 -
seatunnel-config/src/test/resources/test02.conf | 28 -
.../src/test/resources/test03-included.conf | 24 -
seatunnel-config/src/test/resources/test03.conf | 51 -
seatunnel-config/src/test/resources/test04.conf | 320 ----
seatunnel-config/src/test/resources/test05.conf | 169 --
seatunnel-config/src/test/resources/test06.conf | 29 -
seatunnel-config/src/test/resources/test07.conf | 19 -
seatunnel-config/src/test/resources/test08.conf | 21 -
seatunnel-config/src/test/resources/test09.conf | 32 -
seatunnel-config/src/test/resources/test10.conf | 26 -
seatunnel-config/src/test/resources/test11.conf | 22 -
.../src/test/resources/validate-invalid.conf | 45 -
.../src/test/resources/validate-reference.conf | 47 -
.../apache/seatunnel/flink/sink/ConsoleSink.java | 2 +-
.../org/apache/seatunnel/flink/sink/DorisSink.java | 2 +-
.../apache/seatunnel/flink/source/DruidSource.java | 2 +-
.../apache/seatunnel/flink/sink/Elasticsearch.java | 4 +-
.../flink/sink/ElasticsearchOutputFormat.java | 2 +-
.../seatunnel/flink/source/FakeSourceStream.java | 2 +-
.../org/apache/seatunnel/flink/sink/FileSink.java | 2 +-
.../apache/seatunnel/flink/source/FileSource.java | 2 +-
.../org/apache/seatunnel/flink/sink/JdbcSink.java | 2 +-
.../apache/seatunnel/flink/source/JdbcSource.java | 2 +-
.../apache/seatunnel/flink/sink/KafkaTable.java | 2 +-
.../seatunnel/flink/source/KafkaTableStream.java | 2 +-
.../seatunnel/flink/source/SocketStream.java | 2 +-
.../apache/seatunnel/spark/sink/Clickhouse.scala | 2 +-
.../org/apache/seatunnel/spark/sink/Console.scala | 2 +-
.../seatunnel/spark/sink/Elasticsearch.scala | 2 +-
.../apache/seatunnel/spark/source/FakeStream.scala | 2 +-
.../apache/seatunnel/spark/sink/FileSinkBase.scala | 2 +-
.../org/apache/seatunnel/spark/sink/Hbase.scala | 2 +-
.../org/apache/seatunnel/spark/sink/Hudi.scala | 2 +-
.../org/apache/seatunnel/spark/sink/Jdbc.scala | 2 +-
.../org/apache/seatunnel/spark/sink/Kafka.scala | 2 +-
.../seatunnel/spark/source/KafkaStream.scala | 2 +-
.../seatunnel/spark/source/SocketStream.scala | 2 +-
.../org/apache/seatunnel/config/ConfigBuilder.java | 4 +
.../apache/seatunnel/config/ExposeSparkConf.java | 5 +
.../flink/transform/DataStreamToTable.java | 2 +-
.../apache/seatunnel/flink/transform/Split.java | 2 +-
.../org/apache/seatunnel/flink/transform/Sql.java | 2 +-
.../flink/transform/TableToDataStream.java | 2 +-
.../apache/seatunnel/spark/transform/Json.scala | 2 +-
.../apache/seatunnel/spark/transform/Split.scala | 2 +-
tools/checkstyle/checkStyle.xml | 5 +-
227 files changed, 446 insertions(+), 24132 deletions(-)
diff --git a/pom.xml b/pom.xml
index 9ccf8be..c36284b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,7 +88,6 @@
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
<scala-maven-plugin.version>3.3.1</scala-maven-plugin.version>
<maven-compiler-plugin.version>2.0.2</maven-compiler-plugin.version>
- <maven-shade-plugin.version>2.4.3</maven-shade-plugin.version>
<maven-pmd-plugin.version>3.8</maven-pmd-plugin.version>
<spoiwo.version>1.8.0</spoiwo.version>
<play-mailer.version>7.0.2</play-mailer.version>
@@ -117,6 +116,9 @@
<jcommander.version>1.81</jcommander.version>
<junit.version>4.13.2</junit.version>
<calcite-druid.version>1.29.0</calcite-druid.version>
+ <config.version>1.3.3</config.version>
+ <maven-shade-plugin.version>3.2.4</maven-shade-plugin.version>
+ <maven-helper-plugin.version>3.2.0</maven-helper-plugin.version>
</properties>
<dependencyManagement>
@@ -408,6 +410,11 @@
<artifactId>calcite-druid</artifactId>
<version>${calcite-druid.version}</version>
</dependency>
+ <dependency>
+ <groupId>com.typesafe</groupId>
+ <artifactId>config</artifactId>
+ <version>${config.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
@@ -737,6 +744,18 @@
</executions>
</plugin>
<!-- maven deploy (End) -->
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>${maven-shade-plugin.version}</version>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>${maven-helper-plugin.version}</version>
+ </plugin>
</plugins>
</pluginManagement>
diff --git a/seatunnel-apis/seatunnel-api-base/src/main/java/org/apache/seatunnel/plugin/Plugin.java b/seatunnel-apis/seatunnel-api-base/src/main/java/org/apache/seatunnel/plugin/Plugin.java
index d30af51..ac4d5e0 100644
--- a/seatunnel-apis/seatunnel-api-base/src/main/java/org/apache/seatunnel/plugin/Plugin.java
+++ b/seatunnel-apis/seatunnel-api-base/src/main/java/org/apache/seatunnel/plugin/Plugin.java
@@ -17,7 +17,7 @@
package org.apache.seatunnel.plugin;
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
import org.apache.seatunnel.common.config.CheckResult;
import java.io.Serializable;
diff --git a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/FlinkEnvironment.java b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/FlinkEnvironment.java
index 22dec68..428b0b7 100644
--- a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/FlinkEnvironment.java
+++ b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/FlinkEnvironment.java
@@ -17,7 +17,7 @@
package org.apache.seatunnel.flink;
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
import org.apache.seatunnel.env.RuntimeEnv;
import org.apache.seatunnel.flink.util.ConfigKeyName;
import org.apache.seatunnel.flink.util.EnvironmentUtil;
diff --git a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/batch/FlinkBatchExecution.java b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/batch/FlinkBatchExecution.java
index a6faa08..18bb8cd 100644
--- a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/batch/FlinkBatchExecution.java
+++ b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/batch/FlinkBatchExecution.java
@@ -17,7 +17,7 @@
package org.apache.seatunnel.flink.batch;
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
import org.apache.seatunnel.env.Execution;
import org.apache.seatunnel.flink.FlinkEnvironment;
import org.apache.seatunnel.flink.util.TableUtil;
diff --git a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/stream/FlinkStreamExecution.java b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/stream/FlinkStreamExecution.java
index f91b76d..ee5a361 100644
--- a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/stream/FlinkStreamExecution.java
+++ b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/stream/FlinkStreamExecution.java
@@ -17,7 +17,7 @@
package org.apache.seatunnel.flink.stream;
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
import org.apache.seatunnel.env.Execution;
import org.apache.seatunnel.flink.FlinkEnvironment;
import org.apache.seatunnel.flink.util.TableUtil;
diff --git a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/EnvironmentUtil.java b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/EnvironmentUtil.java
index 6e515ed..9e21b0f 100644
--- a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/EnvironmentUtil.java
+++ b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/EnvironmentUtil.java
@@ -17,7 +17,7 @@
package org.apache.seatunnel.flink.util;
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
import org.apache.seatunnel.common.config.CheckResult;
import org.apache.flink.api.common.ExecutionConfig;
import org.apache.flink.api.common.restartstrategy.RestartStrategies;
diff --git a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/SchemaUtil.java b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/SchemaUtil.java
index 9a71834..1b8cb4b 100644
--- a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/SchemaUtil.java
+++ b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/SchemaUtil.java
@@ -19,8 +19,8 @@ package org.apache.seatunnel.flink.util;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
-import org.apache.seatunnel.config.Config;
-import org.apache.seatunnel.config.ConfigValue;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.ConfigValue;
import org.apache.commons.lang3.StringUtils;
import org.apache.flink.api.common.typeinfo.TypeInformation;
import org.apache.flink.api.java.typeutils.ObjectArrayTypeInfo;
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSink.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSink.scala
index aef5e05..fc8cf17 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSink.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSink.scala
@@ -17,7 +17,7 @@
package org.apache.seatunnel.spark
import org.apache.seatunnel.apis.BaseSink
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
import org.apache.spark.sql.{Dataset, Row}
trait BaseSparkSink[OUT] extends BaseSink[SparkEnvironment] {
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSource.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSource.scala
index 71877ca..0b6afa5 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSource.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSource.scala
@@ -17,7 +17,7 @@
package org.apache.seatunnel.spark
import org.apache.seatunnel.apis.BaseSource
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
trait BaseSparkSource[Data] extends BaseSource[SparkEnvironment] {
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkTransform.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkTransform.scala
index ca904b1..d964d93 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkTransform.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkTransform.scala
@@ -18,7 +18,7 @@ package org.apache.seatunnel.spark
import org.apache.spark.sql.{Dataset, Row}
import org.apache.seatunnel.apis.BaseTransform
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
trait BaseSparkTransform extends BaseTransform[SparkEnvironment] {
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/SparkEnvironment.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/SparkEnvironment.scala
index 9e92146..cb0b57f 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/SparkEnvironment.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/SparkEnvironment.scala
@@ -17,7 +17,7 @@
package org.apache.seatunnel.spark
import org.apache.seatunnel.common.config.CheckResult
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
import org.apache.seatunnel.env.RuntimeEnv
import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/batch/SparkBatchExecution.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/batch/SparkBatchExecution.scala
index 285855f..9ed16fc 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/batch/SparkBatchExecution.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/batch/SparkBatchExecution.scala
@@ -17,7 +17,7 @@
package org.apache.seatunnel.spark.batch
import org.apache.seatunnel.common.config.{CheckResult, ConfigRuntimeException}
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
import org.apache.seatunnel.env.Execution
import org.apache.seatunnel.spark.{BaseSparkSink, BaseSparkSource, BaseSparkTransform, SparkEnvironment}
import org.apache.spark.sql.{Dataset, Row}
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/stream/SparkStreamingExecution.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/stream/SparkStreamingExecution.scala
index 56b3a63..0c4e9b2 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/stream/SparkStreamingExecution.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/stream/SparkStreamingExecution.scala
@@ -17,7 +17,7 @@
package org.apache.seatunnel.spark.stream
import org.apache.seatunnel.common.config.CheckResult
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
import org.apache.seatunnel.env.Execution
import org.apache.seatunnel.spark.batch.SparkBatchExecution
import org.apache.seatunnel.spark.{BaseSparkSink, BaseSparkSource, BaseSparkTransform, SparkEnvironment}
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/structuredstream/StructuredStreamingExecution.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/structuredstream/StructuredStreamingExecution.scala
index 3f8a488..6505d81 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/structuredstream/StructuredStreamingExecution.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/structuredstream/StructuredStreamingExecution.scala
@@ -17,7 +17,7 @@
package org.apache.seatunnel.spark.structuredstream
import org.apache.seatunnel.common.config.CheckResult
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
import org.apache.seatunnel.env.Execution
import org.apache.seatunnel.spark.{BaseSparkTransform, SparkEnvironment}
diff --git a/seatunnel-common/src/main/java/org/apache/seatunnel/common/PropertiesUtil.java b/seatunnel-common/src/main/java/org/apache/seatunnel/common/PropertiesUtil.java
index 764d152..25b242e 100644
--- a/seatunnel-common/src/main/java/org/apache/seatunnel/common/PropertiesUtil.java
+++ b/seatunnel-common/src/main/java/org/apache/seatunnel/common/PropertiesUtil.java
@@ -17,7 +17,7 @@
package org.apache.seatunnel.common;
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
import java.util.Properties;
diff --git a/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/CheckConfigUtil.java b/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/CheckConfigUtil.java
index 4b39f5c..1ce9605 100644
--- a/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/CheckConfigUtil.java
+++ b/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/CheckConfigUtil.java
@@ -17,7 +17,7 @@
package org.apache.seatunnel.common.config;
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
public class CheckConfigUtil {
diff --git a/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/TypesafeConfigUtils.java b/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/TypesafeConfigUtils.java
index 722a32f..0fe1216 100644
--- a/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/TypesafeConfigUtils.java
+++ b/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/TypesafeConfigUtils.java
@@ -17,9 +17,9 @@
package org.apache.seatunnel.common.config;
-import org.apache.seatunnel.config.Config;
-import org.apache.seatunnel.config.ConfigFactory;
-import org.apache.seatunnel.config.ConfigValue;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.ConfigFactory;
+import org.apache.seatunnel.shade.com.typesafe.config.ConfigValue;
import java.util.LinkedHashMap;
import java.util.Map;
diff --git a/seatunnel-config/HOCON.md b/seatunnel-config/HOCON.md
deleted file mode 100644
index 6e0818c..0000000
--- a/seatunnel-config/HOCON.md
+++ /dev/null
@@ -1,1625 +0,0 @@
-<!-- START doctoc generated TOC please keep comment here to allow auto update -->
-<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
-**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
-
-- [HOCON (Human-Optimized Config Object Notation)](#hocon-human-optimized-config-object-notation)
- - [Goals / Background](#goals--background)
- - [Definitions](#definitions)
- - [Syntax](#syntax)
- - [Unchanged from JSON](#unchanged-from-json)
- - [Comments](#comments)
- - [Omit root braces](#omit-root-braces)
- - [Key-value separator](#key-value-separator)
- - [Commas](#commas)
- - [Whitespace](#whitespace)
- - [Duplicate keys and object merging](#duplicate-keys-and-object-merging)
- - [Unquoted strings](#unquoted-strings)
- - [Multi-line strings](#multi-line-strings)
- - [Value concatenation](#value-concatenation)
- - [String value concatenation](#string-value-concatenation)
- - [Array and object concatenation](#array-and-object-concatenation)
- - [Note: Concatenation with whitespace and substitutions](#note-concatenation-with-whitespace-and-substitutions)
- - [Note: Arrays without commas or newlines](#note-arrays-without-commas-or-newlines)
- - [Path expressions](#path-expressions)
- - [Paths as keys](#paths-as-keys)
- - [Substitutions](#substitutions)
- - [Self-Referential Substitutions](#self-referential-substitutions)
- - [The `+=` field separator](#the--field-separator)
- - [Examples of Self-Referential Substitutions](#examples-of-self-referential-substitutions)
- - [Includes](#includes)
- - [Include syntax](#include-syntax)
- - [Include semantics: merging](#include-semantics-merging)
- - [Include semantics: substitution](#include-semantics-substitution)
- - [Include semantics: missing files and required files](#include-semantics-missing-files-and-required-files)
- - [Include semantics: file formats and extensions](#include-semantics-file-formats-and-extensions)
- - [Include semantics: locating resources](#include-semantics-locating-resources)
- - [Conversion of numerically-indexed objects to arrays](#conversion-of-numerically-indexed-objects-to-arrays)
- - [MIME Type](#mime-type)
- - [API Recommendations](#api-recommendations)
- - [Automatic type conversions](#automatic-type-conversions)
- - [Units format](#units-format)
- - [Duration format](#duration-format)
- - [Size in bytes format](#size-in-bytes-format)
- - [Config object merging and file merging](#config-object-merging-and-file-merging)
- - [Java properties mapping](#java-properties-mapping)
- - [Conventional configuration files for JVM apps](#conventional-configuration-files-for-jvm-apps)
- - [Conventional override by system properties](#conventional-override-by-system-properties)
- - [Substitution fallback to environment variables](#substitution-fallback-to-environment-variables)
- - [hyphen-separated vs. camelCase](#hyphen-separated-vs-camelcase)
- - [Note on Java properties similarity](#note-on-java-properties-similarity)
- - [Note on Windows and case sensitivity of environment variables](#note-on-windows-and-case-sensitivity-of-environment-variables)
-
-<!-- END doctoc generated TOC please keep comment here to allow auto update -->
-
-# HOCON (Human-Optimized Config Object Notation)
-
-This is an informal spec, but hopefully it's clear.
-
-## Goals / Background
-
-The primary goal is: keep the semantics (tree structure; set of
-types; encoding/escaping) from JSON, but make it more convenient
-as a human-editable config file format.
-
-The following features are desirable, to support human usage:
-
- - less noisy / less pedantic syntax
- - ability to refer to another part of the configuration (set a value to
- another value)
- - import/include another configuration file into the current file
- - a mapping to a flat properties list such as Java's system properties
- - ability to get values from environment variables
- - ability to write comments
-
-Implementation-wise, the format should have these properties:
-
- - a JSON superset, that is, all valid JSON should be valid and
- should result in the same in-memory data that a JSON parser
- would have produced.
- - be deterministic; the format is flexible, but it is not
- heuristic. It should be clear what's invalid and invalid files
- should generate errors.
- - require minimal look-ahead; should be able to tokenize the file
- by looking at only the next three characters. (right now, the
- only reason to look at three is to find "//" comments;
- otherwise you can parse looking at two.)
-
-HOCON is significantly harder to specify and to parse than
-JSON. Think of it as moving the work from the person maintaining
-the config file to the computer program.
-
-## Definitions
-
- - a _key_ is a string JSON would have to the left of `:` and a _value_ is
- anything JSON would have to the right of `:`. i.e. the two
- halves of an object _field_.
-
- - a _value_ is any "value" as defined in the JSON spec, plus
- unquoted strings and substitutions as defined in this spec.
-
- - a _simple value_ is any value excluding an object or array
- value.
-
- - a _field_ is a key, any separator such as ':', and a value.
-
- - references to a _file_ ("the file being parsed") can be
- understood to mean any byte stream being parsed, not just
- literal files in a filesystem.
-
-## Syntax
-
-Much of this is defined with reference to JSON; you can find the
-JSON spec at https://json.org/ of course.
-
-### Unchanged from JSON
-
- - files must be valid UTF-8
- - quoted strings are in the same format as JSON strings
- - values have possible types: string, number, object, array, boolean, null
- - allowed number formats matches JSON; as in JSON, some possible
- floating-point values are not represented, such as `NaN`
-
-### Comments
-
-Anything between `//` or `#` and the next newline is considered a comment
-and ignored, unless the `//` or `#` is inside a quoted string.
-
-### Omit root braces
-
-JSON documents must have an array or object at the root. Empty
-files are invalid documents, as are files containing only a
-non-array non-object value such as a string.
-
-In HOCON, if the file does not begin with a square bracket or
-curly brace, it is parsed as if it were enclosed with `{}` curly
-braces.
-
-A HOCON file is invalid if it omits the opening `{` but still has
-a closing `}`; the curly braces must be balanced.
-
-### Key-value separator
-
-The `=` character can be used anywhere JSON allows `:`, i.e. to
-separate keys from values.
-
-If a key is followed by `{`, the `:` or `=` may be omitted. So
-`"foo" {}` means `"foo" : {}`
-
-### Commas
-
-Values in arrays, and fields in objects, need not have a comma
-between them as long as they have at least one ASCII newline
-(`\n`, decimal value 10) between them.
-
-The last element in an array or last field in an object may be
-followed by a single comma. This extra comma is ignored.
-
- - `[1,2,3,]` and `[1,2,3]` are the same array.
- - `[1\n2\n3]` and `[1,2,3]` are the same array.
- - `[1,2,3,,]` is invalid because it has two trailing commas.
- - `[,1,2,3]` is invalid because it has an initial comma.
- - `[1,,2,3]` is invalid because it has two commas in a row.
- - these same comma rules apply to fields in objects.
-
-### Whitespace
-
-The JSON spec simply says "whitespace"; in HOCON whitespace is
-defined as follows:
-
- - any Unicode space separator (Zs category), line separator (Zl
- category), or paragraph separator (Zp category), including
- nonbreaking spaces (such as 0x00A0, 0x2007, and 0x202F).
- The BOM (0xFEFF) must also be treated as whitespace.
- - tab (`\t` 0x0009), newline ('\n' 0x000A), vertical tab ('\v'
- 0x000B)`, form feed (`\f' 0x000C), carriage return ('\r'
- 0x000D), file separator (0x001C), group separator (0x001D),
- record separator (0x001E), unit separator (0x001F).
-
-In Java, the `isWhitespace()` method covers these characters with
-the exception of nonbreaking spaces and the BOM.
-
-While all Unicode separators should be treated as whitespace, in
-this spec "newline" refers only and specifically to ASCII newline
-0x000A.
-
-### Duplicate keys and object merging
-
-The JSON spec does not clarify how duplicate keys in the same
-object should be handled. In HOCON, duplicate keys that appear
-later override those that appear earlier, unless both values are
-objects. If both values are objects, then the objects are merged.
-
-Note: this would make HOCON a non-superset of JSON if you assume
-that JSON requires duplicate keys to have a behavior. The
-assumption here is that duplicate keys are invalid JSON.
-
-To merge objects:
-
- - add fields present in only one of the two objects to the merged
- object.
- - for non-object-valued fields present in both objects,
- the field found in the second object must be used.
- - for object-valued fields present in both objects, the
- object values should be recursively merged according to
- these same rules.
-
-Object merge can be prevented by setting the key to another value
-first. This is because merging is always done two values at a
-time; if you set a key to an object, a non-object, then an object,
-first the non-object falls back to the object (non-object always
-wins), and then the object falls back to the non-object (no
-merging, object is the new value). So the two objects never see
-each other.
-
-These two are equivalent:
-
- {
- "foo" : { "a" : 42 },
- "foo" : { "b" : 43 }
- }
-
- {
- "foo" : { "a" : 42, "b" : 43 }
- }
-
-And these two are equivalent:
-
- {
- "foo" : { "a" : 42 },
- "foo" : null,
- "foo" : { "b" : 43 }
- }
-
- {
- "foo" : { "b" : 43 }
- }
-
-The intermediate setting of `"foo"` to `null` prevents the object merge.
-
-### Unquoted strings
-
-A sequence of characters outside of a quoted string is a string
-value if:
-
- - it does not contain "forbidden characters": '$', '"', '{', '}',
- '[', ']', ':', '=', ',', '+', '#', '`', '^', '?', '!', '@',
- '*', '&', '\' (backslash), or whitespace.
- - it does not contain the two-character string "//" (which
- starts a comment)
- - its initial characters do not parse as `true`, `false`, `null`,
- or a number.
-
-Unquoted strings are used literally, they do not support any kind
-of escaping. Quoted strings may always be used as an alternative
-when you need to write a character that is not permitted in an
-unquoted string.
-
-`truefoo` parses as the boolean token `true` followed by the
-unquoted string `foo`. However, `footrue` parses as the unquoted
-string `footrue`. Similarly, `10.0bar` is the number `10.0` then
-the unquoted string `bar` but `bar10.0` is the unquoted string
-`bar10.0`. (In practice, this distinction doesn't matter much
-because of value concatenation; see later section.)
-
-In general, once an unquoted string begins, it continues until a
-forbidden character or the two-character string "//" is
-encountered. Embedded (non-initial) booleans, nulls, and numbers
-are not recognized as such, they are part of the string.
-
-An unquoted string may not _begin_ with the digits 0-9 or with a
-hyphen (`-`, 0x002D) because those are valid characters to begin a
-JSON number. The initial number character, plus any valid-in-JSON
-number characters that follow it, must be parsed as a number
-value. Again, these characters are not special _inside_ an
-unquoted string; they only trigger number parsing if they appear
-initially.
-
-Note that quoted JSON strings may not contain control characters
-(control characters include some whitespace characters, such as
-newline). This rule is from the JSON spec. However, unquoted
-strings have no restriction on control characters, other than the
-ones listed as "forbidden characters" above.
-
-Some of the "forbidden characters" are forbidden because they
-already have meaning in JSON or HOCON, others are essentially
-reserved keywords to allow future extensions to this spec.
-
-### Multi-line strings
-
-Multi-line strings are similar to Python or Scala, using triple
-quotes. If the three-character sequence `"""` appears, then all
-Unicode characters until a closing `"""` sequence are used
-unmodified to create a string value. Newlines and whitespace
-receive no special treatment. Unlike Scala, and unlike JSON quoted
-strings, Unicode escapes are not interpreted in triple-quoted
-strings.
-
-In Python, `"""foo""""` is a syntax error (a triple-quoted string
-followed by a dangling unbalanced quote). In Scala, it is a
-four-character string `foo"`. HOCON works like Scala; any sequence
-of at least three quotes ends the multi-line string, and any
-"extra" quotes are part of the string.
-
-### Value concatenation
-
-The value of an object field or array element may consist of
-multiple values which are combined. There are three kinds of value
-concatenation:
-
- - if all the values are simple values (neither objects nor
- arrays), they are concatenated into a string.
- - if all the values are arrays, they are concatenated into
- one array.
- - if all the values are objects, they are merged (as with
- duplicate keys) into one object.
-
-String value concatenation is allowed in field keys, in addition
-to field values and array elements. Objects and arrays do not make
-sense as field keys.
-
-Note: Akka 2.0 (and thus Play 2.0) contains an embedded
-implementation of the config lib which does not support array and
-object value concatenation; it only supports string value
-concatenation.
-
-#### String value concatenation
-
-String value concatenation is the trick that makes unquoted
-strings work; it also supports substitutions (`${foo}` syntax) in
-strings.
-
-Only simple values participate in string value
-concatenation. Recall that a simple value is any value other than
-arrays and objects.
-
-As long as simple values are separated only by non-newline
-whitespace, the _whitespace between them is preserved_ and the
-values, along with the whitespace, are concatenated into a string.
-
-String value concatenations never span a newline, or a character
-that is not part of a simple value.
-
-A string value concatenation may appear in any place that a string
-may appear, including object keys, object values, and array
-elements.
-
-Whenever a value would appear in JSON, a HOCON parser instead
-collects multiple values (including the whitespace between them)
-and concatenates those values into a string.
-
-Whitespace before the first and after the last simple value must
-be discarded. Only whitespace _between_ simple values must be
-preserved.
-
-So for example ` foo bar baz ` parses as three unquoted strings,
-and the three are value-concatenated into one string. The inner
-whitespace is kept and the leading and trailing whitespace is
-trimmed. The equivalent string, written in quoted form, would be
-`"foo bar baz"`.
-
-Value concatenating `foo bar` (two unquoted strings with
-whitespace) and quoted string `"foo bar"` would result in the same
-in-memory representation, seven characters.
-
-For purposes of string value concatenation, non-string values are
-converted to strings as follows (strings shown as quoted strings):
-
- - `true` and `false` become the strings `"true"` and `"false"`.
- - `null` becomes the string `"null"`.
- - quoted and unquoted strings are themselves.
- - numbers should be kept as they were originally written in the
- file. For example, if you parse `1e5` then you might render
- it alternatively as `1E5` with capital `E`, or just `100000`.
- For purposes of value concatenation, it should be rendered
- as it was written in the file.
- - a substitution is replaced with its value which is then
- converted to a string as above.
- - it is invalid for arrays or objects to appear in a string value
- concatenation.
-
-A single value is never converted to a string. That is, it would
-be wrong to value concatenate `true` by itself; that should be
-parsed as a boolean-typed value. Only `true foo` (`true` with
-another simple value on the same line) should be parsed as a value
-concatenation and converted to a string.
-
-#### Array and object concatenation
-
-Arrays can be concatenated with arrays, and objects with objects,
-but it is an error if they are mixed.
-
-For purposes of concatenation, "array" also means "substitution
-that resolves to an array" and "object" also means "substitution
-that resolves to an object."
-
-Within an field value or array element, if only non-newline
-whitespace separates the end of a first array or object or
-substitution from the start of a second array or object or
-substitution, the two values are concatenated. Newlines may occur
-_within_ the array or object, but not _between_ them. Newlines
-_between_ prevent concatenation.
-
-For objects, "concatenation" means "merging", so the second object
-overrides the first.
-
-Arrays and objects cannot be field keys, whether concatenation is
-involved or not.
-
-Here are several ways to define `a` to the same object value:
-
- // one object
- a : { b : 1, c : 2 }
- // two objects that are merged via concatenation rules
- a : { b : 1 } { c : 2 }
- // two fields that are merged
- a : { b : 1 }
- a : { c : 2 }
-
-Here are several ways to define `a` to the same array value:
-
- // one array
- a : [ 1, 2, 3, 4 ]
- // two arrays that are concatenated
- a : [ 1, 2 ] [ 3, 4 ]
- // a later definition referring to an earlier
- // (see "self-referential substitutions" below)
- a : [ 1, 2 ]
- a : ${a} [ 3, 4 ]
-
-A common use of object concatenation is "inheritance":
-
- data-center-generic = { cluster-size = 6 }
- data-center-east = ${data-center-generic} { name = "east" }
-
-A common use of array concatenation is to add to paths:
-
- path = [ /bin ]
- path = ${path} [ /usr/bin ]
-
-#### Note: Concatenation with whitespace and substitutions
-
-When concatenating substitutions such as `${foo} ${bar}`, the
-substitutions may turn out to be strings (which makes the
-whitespace between them significant) or may turn out to be objects
-or lists (which makes it irrelevant). Unquoted whitespace must be
-ignored in between substitutions which resolve to objects or
-lists. Quoted whitespace should be an error.
-
-#### Note: Arrays without commas or newlines
-
-Arrays allow you to use newlines instead of commas, but not
-whitespace instead of commas. Non-newline whitespace will produce
-concatenation rather than separate elements.
-
- // this is an array with one element, the string "1 2 3 4"
- [ 1 2 3 4 ]
- // this is an array of four integers
- [ 1
- 2
- 3
- 4 ]
-
- // an array of one element, the array [ 1, 2, 3, 4 ]
- [ [ 1, 2 ] [ 3, 4 ] ]
- // an array of two arrays
- [ [ 1, 2 ]
- [ 3, 4 ] ]
-
-If this gets confusing, just use commas. The concatenation
-behavior is useful rather than surprising in cases like:
-
- [ This is an unquoted string my name is ${name}, Hello ${world} ]
- [ ${a} ${b}, ${x} ${y} ]
-
-Non-newline whitespace is never an element or field separator.
-
-### Path expressions
-
-Path expressions are used to write out a path through the object
-graph. They appear in two places; in substitutions, like
-`${foo.bar}`, and as the keys in objects like `{ foo.bar : 42 }`.
-
-Path expressions are syntactically identical to a value
-concatenation, except that they may not contain
-substitutions. This means that you can't nest substitutions inside
-other substitutions, and you can't have substitutions in keys.
-
-When concatenating the path expression, any `.` characters outside
-quoted strings are understood as path separators, while inside
-quoted strings `.` has no special meaning. So
-`foo.bar."hello.world"` would be a path with three elements,
-looking up key `foo`, key `bar`, then key `hello.world`.
-
-The main tricky point is that `.` characters in numbers do count
-as a path separator. When dealing with a number as part of a path
-expression, it's essential to retain the _original_ string
-representation of the number as it appeared in the file (rather
-than converting it back to a string with a generic
-number-to-string library function).
-
- - `10.0foo` is a number then unquoted string `foo` and should
- be the two-element path with `10` and `0foo` as the elements.
- - `foo10.0` is an unquoted string with a `.` in it, so this would
- be a two-element path with `foo10` and `0` as the elements.
- - `foo"10.0"` is an unquoted then a quoted string which are
- concatenated, so this is a single-element path.
- - `1.2.3` is the three-element path with `1`,`2`,`3`
-
-Unlike value concatenations, path expressions are _always_
-converted to a string, even if they are just a single value.
-
-If you have an array or element value consisting of the single
-value `true`, it's a value concatenation and retains its character
-as a boolean value.
-
-If you have a path expression (in a key or substitution) then it
-must always be converted to a string, so `true` becomes the string
-that would be quoted as `"true"`.
-
-If a path element is an empty string, it must always be quoted.
-That is, `a."".b` is a valid path with three elements, and the
-middle element is an empty string. But `a..b` is invalid and
-should generate an error. Following the same rule, a path that
-starts or ends with a `.` is invalid and should generate an error.
-
-### Paths as keys
-
-If a key is a path expression with multiple elements, it is
-expanded to create an object for each path element other than the
-last. The last path element, combined with the value, becomes a
-field in the most-nested object.
-
-In other words:
-
- foo.bar : 42
-
-is equivalent to:
-
- foo { bar : 42 }
-
-and:
-
- foo.bar.baz : 42
-
-is equivalent to:
-
- foo { bar { baz : 42 } }
-
-and so on. These values are merged in the usual way; which implies
-that:
-
- a.x : 42, a.y : 43
-
-is equivalent to:
-
- a { x : 42, y : 43 }
-
-Because path expressions work like value concatenations, you can
-have whitespace in keys:
-
- a b c : 42
-
-is equivalent to:
-
- "a b c" : 42
-
-Because path expressions are always converted to strings, even
-single values that would normally have another type become
-strings.
-
- - `true : 42` is `"true" : 42`
- - `3 : 42` is `"3" : 42`
- - `3.14 : 42` is `"3" : { "14" : 42 }`
-
-As a special rule, the unquoted string `include` may not begin a
-path expression in a key, because it has a special interpretation
-(see below).
-
-### Substitutions
-
-Substitutions are a way of referring to other parts of the
-configuration tree.
-
-The syntax is `${pathexpression}` or `${?pathexpression}` where
-the `pathexpression` is a path expression as described above. This
-path expression has the same syntax that you could use for an
-object key.
-
-The `?` in `${?pathexpression}` must not have whitespace before
-it; the three characters `${?` must be exactly like that, grouped
-together.
-
-For substitutions which are not found in the configuration tree,
-implementations may try to resolve them by looking at system
-environment variables or other external sources of configuration.
-(More detail on environment variables in a later section.)
-
-Substitutions are not parsed inside quoted strings. To get a
-string containing a substitution, you must use value concatenation
-with the substitution in the unquoted portion:
-
- key : ${animal.favorite} is my favorite animal
-
-Or you could quote the non-substitution portion:
-
- key : ${animal.favorite}" is my favorite animal"
-
-Substitutions are resolved by looking up the path in the
-configuration. The path begins with the root configuration object,
-i.e. it is "absolute" rather than "relative."
-
-Substitution processing is performed as the last parsing step, so
-a substitution can look forward in the configuration. If a
-configuration consists of multiple files, it may even end up
-retrieving a value from another file.
-
-If a key has been specified more than once, the substitution will
-always evaluate to its latest-assigned value (that is, it will
-evaluate to the merged object, or the last non-object value that
-was set, in the entire document being parsed including all
-included files).
-
-If a configuration sets a value to `null` then it should not be
-looked up in the external source. Unfortunately there is no way to
-"undo" this in a later configuration file; if you have `{ "HOME" :
-null }` in a root object, then `${HOME}` will never look at the
-environment variable. There is no equivalent to JavaScript's
-`delete` operation in other words.
-
-If a substitution does not match any value present in the
-configuration and is not resolved by an external source, then it
-is undefined. An undefined substitution with the `${foo}` syntax
-is invalid and should generate an error.
-
-If a substitution with the `${?foo}` syntax is undefined:
-
- - if it is the value of an object field then the field should not
- be created. If the field would have overridden a previously-set
- value for the same field, then the previous value remains.
- - if it is an array element then the element should not be added.
- - if it is part of a value concatenation with another string then
- it should become an empty string; if part of a value
- concatenation with an object or array it should become an empty
- object or array.
- - `foo : ${?bar}` would avoid creating field `foo` if `bar` is
- undefined. `foo : ${?bar}${?baz}` would also avoid creating the
- field if _both_ `bar` and `baz` are undefined.
-
-Substitutions are only allowed in field values and array
-elements (value concatenations), they are not allowed in keys or
-nested inside other substitutions (path expressions).
-
-A substitution is replaced with any value type (number, object,
-string, array, true, false, null). If the substitution is the only
-part of a value, then the type is preserved. Otherwise, it is
-value-concatenated to form a string.
-
-#### Self-Referential Substitutions
-
-The big picture:
-
- - substitutions normally "look forward" and use the final value
- for their path expression
- - when this would create a cycle, when possible the cycle must be
- broken by looking backward only (thus removing one of the
- substitutions that's a link in the cycle)
-
-The idea is to allow a new value for a field to be based on the
-older value:
-
- path : "a:b:c"
- path : ${path}":d"
-
-A _self-referential field_ is one which:
-
- - has a substitution, or value concatenation containing a
- substitution, as its value
- - where this field value refers to the field being defined,
- either directly or by referring to one or more other
- substitutions which eventually point back to the field being
- defined
-
-Examples of self-referential fields:
-
- - `a : ${a}`
- - `a : ${a}bc`
- - `path : ${path} [ /usr/bin ]`
-
-Note that an object or array with a substitution inside it is
-_not_ considered self-referential for this purpose. The
-self-referential rules do _not_ apply to:
-
- - `a : { b : ${a} }`
- - `a : [${a}]`
-
-These cases are unbreakable cycles that generate an error. (If
-"looking backward" were allowed for these, something like
-`a={ x : 42, y : ${a.x} }` would look backward for a
-nonexistent `a` while resolving `${a.x}`.)
-
-A possible implementation is:
-
- - substitutions are resolved by looking up paths in a document.
- Cycles only arise when the lookup document is an ancestor
- node of the substitution node.
- - while resolving a potentially self-referential field (any
- substitution or value concatenation that contains a
- substitution), remove that field and all fields which override
- it from the lookup document.
-
-The simplest form of this implementation will report a circular
-reference as missing; in `a : ${a}` you would remove `a : ${a}`
-while resolving `${a}`, leaving an empty document to look up
-`${a}` in. You can give a more helpful error message if, rather
-than simply removing the field, you leave a marker value
-describing the cycle. Then generate an error if you return to that
-marker value during resolution.
-
-Cycles should be treated the same as a missing value when
-resolving an optional substitution (i.e. the `${?foo}` syntax).
-If `${?foo}` refers to itself then it's as if it referred to a
-nonexistent value.
-
-#### The `+=` field separator
-
-Fields may have `+=` as a separator rather than `:` or `=`. A
-field with `+=` transforms into a self-referential array
-concatenation, like this:
-
- a += b
-
-becomes:
-
- a = ${?a} [b]
-
-`+=` appends an element to a previous array. If the previous value
-was not an array, an error will result just as it would in the
-long form `a = ${?a} [b]`. Note that the previous value is
-optional (`${?a}` not `${a}`), which allows `a += b` to be the
-first mention of `a` in the file (it is not necessary to have `a =
-[]` first).
-
-Note: Akka 2.0 (and thus Play 2.0) contains an embedded
-implementation of the config lib which does not support `+=`.
-
-#### Examples of Self-Referential Substitutions
-
-In isolation (with no merges involved), a self-referential field
-is an error because the substitution cannot be resolved:
-
- foo : ${foo} // an error
-
-When `foo : ${foo}` is merged with an earlier value for `foo`,
-however, the substitution can be resolved to that earlier value.
-When merging two objects, the self-reference in the overriding
-field refers to the overridden field. Say you have:
-
- foo : { a : 1 }
-
-and then:
-
- foo : ${foo}
-
-Then `${foo}` resolves to `{ a : 1 }`, the value of the overridden
-field.
-
-It would be an error if these two fields were reversed, so first:
-
- foo : ${foo}
-
-and then second:
-
- foo : { a : 1 }
-
-Here the `${foo}` self-reference comes before `foo` has a value,
-so it is undefined, exactly as if the substitution referenced a
-path not found in the document.
-
-Because `foo : ${foo}` conceptually looks to previous definitions
-of `foo` for a value, the error should be treated as "undefined"
-rather than "intractable cycle"; as a result, the optional
-substitution syntax `${?foo}` does not create a cycle:
-
- foo : ${?foo} // this field just disappears silently
-
-If a substitution is hidden by a value that could not be merged
-with it (by a non-object value) then it is never evaluated and no
-error will be reported. So for example:
-
- foo : ${does-not-exist}
- foo : 42
-
-In this case, no matter what `${does-not-exist}` resolves to, we
-know `foo` is `42`, so `${does-not-exist}` is never evaluated and
-there is no error. The same is true for cycles like `foo : ${foo},
-foo : 42`, where the initial self-reference must simply be ignored.
-
-A self-reference resolves to the value "below" even if it's part
-of a path expression. So for example:
-
- foo : { a : { c : 1 } }
- foo : ${foo.a}
- foo : { a : 2 }
-
-Here, `${foo.a}` would refer to `{ c : 1 }` rather than `2` and so
-the final merge would be `{ a : 2, c : 1 }`.
-
-Recall that for a field to be self-referential, it must have a
-substitution or value concatenation as its value. If a field has
-an object or array value, for example, then it is not
-self-referential even if there is a reference to the field itself
-inside that object or array.
-
-Implementations must be careful to allow objects to refer to paths
-within themselves, for example:
-
- bar : { foo : 42,
- baz : ${bar.foo}
- }
-
-Here, if an implementation resolved all substitutions in `bar` as
-part of resolving the substitution `${bar.foo}`, there would be a
-cycle. The implementation must only resolve the `foo` field in
-`bar`, rather than recursing the entire `bar` object.
-
-Because there is no inherent cycle here, the substitution must
-"look forward" (including looking at the field currently being
-defined). To make this clearer, `bar.baz` would be `43` in:
-
- bar : { foo : 42,
- baz : ${bar.foo}
- }
- bar : { foo : 43 }
-
-Mutually-referring objects should also work, and are not
-self-referential (so they look forward):
-
- // bar.a should end up as 4
- bar : { a : ${foo.d}, b : 1 }
- bar.b = 3
- // foo.c should end up as 3
- foo : { c : ${bar.b}, d : 2 }
- foo.d = 4
-
-Another tricky case is an optional self-reference in a value
-concatenation, in this example `a` should be `foo` not `foofoo`
-because the self reference has to "look back" to an undefined `a`:
-
- a = ${?a}foo
-
-In general, in resolving a substitution the implementation must:
-
- - lazy-evaluate the substitution target so there's no
- "circularity by side effect"
- - "look forward" and use the final value for the path
- specified in the substitution
- - if a cycle results, the implementation must "look back"
- in the merge stack to try to resolve the cycle
- - if neither lazy evaluation nor "looking only backward" resolves
- a cycle, the substitution is missing which is an error unless
- the `${?foo}` optional-substitution syntax was used.
-
-For example, this is not possible to resolve:
-
- bar : ${foo}
- foo : ${bar}
-
-A multi-step loop like this should also be detected as invalid:
-
- a : ${b}
- b : ${c}
- c : ${a}
-
-Some cases have undefined behavior because the behavior depends on
-the order in which two fields are resolved, and that order is not
-defined. For example:
-
- a : 1
- b : 2
- a : ${b}
- b : ${a}
-
-Implementations are allowed to handle this by setting both `a` and
-`b` to 1, setting both to `2`, or generating an error. Ideally
-this situation would generate an error, but that may be difficult
-to implement. Making the behavior defined would require always
-working with ordered maps rather than unordered maps, which is too
-constraining. Implementations only have to track order for
-duplicate instances of the same field (i.e. merges).
-
-Implementations must set both `a` and `b` to the same value in
-this case, however. In practice this means that all substitutions
-must be memoized (resolved once, with the result
-retained). Memoization should be keyed by the substitution
-"instance" (the specific occurrence of the `${}` expression)
-rather than by the path inside the `${}` expression, because
-substitutions may be resolved differently depending on their
-position in the file.
-
-### Includes
-
-#### Include syntax
-
-An _include statement_ consists of the unquoted string `include`
-followed by whitespace and then either:
- - a single _quoted_ string which is interpreted heuristically as
- URL, filename, or classpath resource.
- - `url()`, `file()`, or `classpath()` surrounding a quoted string
- which is then interpreted as a URL, file, or classpath. The
- string must be quoted, unlike in CSS.
- - `required()` surrounding one of the above
-
-An include statement can appear in place of an object field.
-
-If the unquoted string `include` appears at the start of a path
-expression where an object key would be expected, then it is not
-interpreted as a path expression or a key.
-
-Instead, the next value must be a _quoted_ string or a quoted
-string surrounded by `url()`, `file()`, or `classpath()`.
-This value is the _resource name_.
-
-Together, the unquoted `include` and the resource name substitute
-for an object field syntactically, and are separated from the
-following object fields or includes by the usual comma (and as
-usual the comma may be omitted if there's a newline).
-
-If an unquoted `include` at the start of a key is followed by
-anything other than a single quoted string or the
-`url("")`/`file("")`/`classpath("")` syntax, it is invalid and an
-error should be generated.
-
-There can be any amount of whitespace, including newlines, between
-the unquoted `include` and the resource name. For `url()` etc.,
-whitespace is allowed inside the parentheses `()` (outside of the
-quotes).
-
-Value concatenation is NOT performed on the "argument" to
-`include` or `url()` etc. The argument must be a single quoted
-string. No substitutions are allowed, and the argument may not be
-an unquoted string or any other kind of value.
-
-Unquoted `include` has no special meaning if it is not the start
-of a key's path expression.
-
-It may appear later in the key:
-
- # this is valid
- { foo include : 42 }
- # equivalent to
- { "foo include" : 42 }
-
-It may appear as an object or array value:
-
- { foo : include } # value is the string "include"
- [ include ] # array of one string "include"
-
-You can quote `"include"` if you want a key that starts with the
-word `"include"`, only unquoted `include` is special:
-
- { "include" : 42 }
-
-Note: Akka 2.0 (and thus Play 2.0) contains an embedded
-implementation of the config lib which does not support the
-`url()`/`file()`/`classpath()` syntax. Only the heuristic `include
-"foo"` syntax is supported in that version.
-
-#### Include semantics: merging
-
-An _including file_ contains the include statement and an
-_included file_ is the one specified in the include statement.
-(They need not be regular files on a filesystem, but assume they
-are for the moment.)
-
-An included file must contain an object, not an array. This is
-significant because both JSON and HOCON allow arrays as root
-values in a document.
-
-If an included file contains an array as the root value, it is
-invalid and an error should be generated.
-
-The included file should be parsed, producing a root object. The
-keys from the root object are conceptually substituted for the
-include statement in the including file.
-
- - If a key in the included object occurred prior to the include
- statement in the including object, the included key's value
- overrides or merges with the earlier value, exactly as with
- duplicate keys found in a single file.
- - If the including file repeats a key from an earlier-included
- object, the including file's value would override or merge
- with the one from the included file.
-
-#### Include semantics: substitution
-
-Substitutions in included files are looked up at two different
-paths; first, relative to the root of the included file; second,
-relative to the root of the including configuration.
-
-Recall that substitution happens as a final step, _after_
-parsing. It should be done for the entire app's configuration, not
-for single files in isolation.
-
-Therefore, if an included file contains substitutions, they must
-be "fixed up" to be relative to the app's configuration root.
-
-Say for example that the root configuration is this:
-
- { a : { include "foo.conf" } }
-
-And "foo.conf" might look like this:
-
- { x : 10, y : ${x} }
-
-If you parsed "foo.conf" in isolation, then `${x}` would evaluate
-to 10, the value at the path `x`. If you include "foo.conf" in an
-object at key `a`, however, then it must be fixed up to be
-`${a.x}` rather than `${x}`.
-
-Say that the root configuration redefines `a.x`, like this:
-
- {
- a : { include "foo.conf" }
- a : { x : 42 }
- }
-
-Then the `${x}` in "foo.conf", which has been fixed up to
-`${a.x}`, would evaluate to `42` rather than to `10`.
-Substitution happens _after_ parsing the whole configuration.
-
-However, there are plenty of cases where the included file might
-intend to refer to the application's root config. For example, to
-get a value from a system property or from the reference
-configuration. So it's not enough to only look up the "fixed up"
-path, it's necessary to look up the original path as well.
-
-#### Include semantics: missing files and required files
-
-By default, if an included file does not exist then the include statement should
-be silently ignored (as if the included file contained only an
-empty object).
-
-If however an included resource is mandatory then the name of the
-included resource may be wrapped with `required()`, in which case
-file parsing will fail with an error if the resource cannot be resolved.
-
-The syntax for this is
-
- include required("foo.conf")
- include required(file("foo.conf"))
- include required(classpath("foo.conf"))
- include required(url("http://localhost/foo.conf"))
-
-
-Other IO errors probably should not be ignored but implementations
-will have to make a judgment which IO errors reflect an ignorable
-missing file, and which reflect a problem to bring to the user's
-attention.
-
-#### Include semantics: file formats and extensions
-
-Implementations may support including files in other formats.
-Those formats must be compatible with the JSON type system, or
-have some documented mapping to JSON's type system.
-
-If an implementation supports multiple formats, then the extension
-may be omitted from the name of included files:
-
- include "foo"
-
-If a filename has no extension, the implementation should treat it
-as a basename and try loading the file with all known extensions.
-
-If the file exists with multiple extensions, they should _all_ be
-loaded and merged together.
-
-Files in HOCON format should be parsed last. Files in JSON format
-should be parsed next-to-last.
-
-In short, `include "foo"` might be equivalent to:
-
- include "foo.properties"
- include "foo.json"
- include "foo.conf"
-
-This same extension-based behavior is applied to classpath
-resources and files.
-
-For URLs, a basename without extension is not allowed; only the
-exact URL specified is used. The format will be chosen based on
-the Content-Type if available, or by the extension of the path
-component of the URL if no Content-Type is set. This is true even
-for file: URLs.
-
-#### Include semantics: locating resources
-
-A quoted string not surrounded by `url()`, `file()`, `classpath()`
-must be interpreted heuristically. The heuristic is to treat the
-quoted string as:
-
- - a URL, if the quoted string is a valid URL with a known
- protocol.
- - otherwise, a file or other resource "adjacent to" the one being
- parsed and of the same type as the one being parsed. The meaning
- of "adjacent to", and the string itself, has to be specified
- separately for each kind of resource.
- - On the Java Virtual Machine, if an include statement does not
- identify a valid URL or an existing resource "adjacent to" the
- including resource, implementations may wish to fall back to a
- classpath resource. This allows configurations found in files
- or URLs to access classpath resources in a natural way.
-
-Implementations may vary in the kinds of resources they can
-include.
-
-For resources located on the Java classpath:
-
- - included resources are looked up by calling `getResource()` on
- the same class loader used to look up the including resource.
- - if the included resource name is absolute (starts with '/')
- then it should be passed to `getResource()` with the '/'
- removed.
- - if the included resource name does not start with '/' then it
- should have the "directory" of the including resource
- prepended to it, before passing it to `getResource()`. If the
- including resource is not absolute (no '/') and has no "parent
- directory" (is just a single path element), then the included
- relative resource name should be left as-is.
- - it would be wrong to use `getResource()` to get a URL and then
- locate the included name relative to that URL, because a class
- loader is not required to have a one-to-one mapping between
- paths in its URLs and the paths it handles in `getResource()`.
- In other words, the "adjacent to" computation should be done
- on the resource name not on the resource's URL.
-
-For plain files on the filesystem:
-
- - if the included file is an absolute path then it should be kept
- absolute and loaded as such.
- - if the included file is a relative path, then it should be
- located relative to the directory containing the including
- file. The current working directory of the process parsing a
- file must NOT be used when interpreting included paths.
- - if the file is not found, fall back to the classpath resource.
- The classpath resource should not have any package name added
- in front, it should be relative to the "root"; which means any
- leading "/" should just be removed (absolute is the same as
- relative since it's root-relative). The "/" is handled for
- consistency with including resources from inside other
- classpath resources, where the resource name may not be
- root-relative and "/" allows specifying relative to root.
-
-URLs:
-
- - for files loaded from a URL, "adjacent to" should be based
- on parsing the URL's path component, replacing the last
- path element with the included name.
- - file: URLs should behave in exactly the same way as a plain
- filename
-
-Implementations need not support files, Java resources, or URLs;
-and they need not support particular URL protocols. However, if
-they do support them they should do so as described above.
-
-Note that at present, if `url()`/`file()`/`classpath()` are
-specified, the included items are NOT interpreted relative to the
-including items. Relative-to-including-file paths only work with
-the heuristic `include "foo.conf"`. This may change in the future.
-
-### Conversion of numerically-indexed objects to arrays
-
-In some file formats and contexts, such as Java properties files,
-there isn't a good way to define arrays. To provide some mechanism
-for this, implementations should support converting objects with
-numeric keys into arrays. For example, this object:
-
- { "0" : "a", "1" : "b" }
-
-could be treated as:
-
- [ "a", "b" ]
-
-This allows creating an array in a properties file like this:
-
- foo.0 = "a"
- foo.1 = "b"
-
-The details:
-
- - the conversion should be done lazily when required to avoid
- a type error, NOT eagerly anytime an object has numeric
- keys.
- - the conversion should be done when you would do an automatic
- type conversion (see the section "Automatic type conversions"
- below).
- - the conversion should be done in a concatenation when a list
- is expected and an object with numeric keys is found.
- - the conversion should not occur if the object is empty or
- has no keys which parse as positive integers.
- - the conversion should ignore any keys which do not parse
- as positive integers.
- - the conversion should sort by the integer value of each
- key and then build the array; if the integer keys are "0" and
- "2" then the resulting array would have indices "0" and "1",
- i.e. missing indices in the object are eliminated.
-
-## MIME Type
-
-Use "application/hocon" for Content-Type.
-
-## API Recommendations
-
-Implementations of HOCON ideally follow certain conventions and
-work in a predictable way.
-
-### Automatic type conversions
-
-If an application asks for a value with a particular type, the
-implementation should attempt to convert types as follows:
-
- - number to string: convert the number into a string
- representation that would be a valid number in JSON.
- - boolean to string: should become the string "true" or "false"
- - string to number: parse the number with the JSON rules
- - string to boolean: the strings "true", "yes", "on", "false",
- "no", "off" should be converted to boolean values. It's
- tempting to support a long list of other ways to write a
- boolean, but for interoperability and keeping it simple, it's
- recommended to stick to these six.
- - string to null: the string `"null"` should be converted to a
- null value if the application specifically asks for a null
- value, though there's probably no reason an app would do this.
- - numerically-indexed object to array: see the section
- "Conversion of numerically-indexed objects to arrays" above
-
-The following type conversions should NOT be performed:
-
- - null to anything: If the application asks for a specific type
- and finds null instead, that should usually result in an error.
- - object to anything
- - array to anything
- - anything to object
- - anything to array, with the exception of numerically-indexed
- object to array
-
-Converting objects and arrays to and from strings is tempting, but
-in practical situations raises thorny issues of quoting and
-double-escaping.
-
-### Units format
-
-Implementations may wish to support interpreting a value with some
-family of units, such as time units or memory size units: `10ms`
-or `512K`. HOCON does not have an extensible type system and there
-is no way to add a "duration" type. However, for example, if an
-application asks for milliseconds, the implementation can try to
-interpret a value as a milliseconds value.
-
-If an API supports this, for each family of units it should define
-a default unit in the family. For example, the family of duration
-units might default to milliseconds (see below for details on
-durations). The implementation should then interpret values as
-follows:
-
- - if the value is a number, it is taken to be a number in
- the default unit.
- - if the value is a string, it is taken to be this sequence:
-
- - optional whitespace
- - a number
- - optional whitespace
- - an optional unit name consisting only of letters (letters
- are the Unicode `L*` categories, Java `isLetter()`)
- - optional whitespace
-
- If a string value has no unit name, then it should be
- interpreted with the default unit, as if it were a number. If a
- string value has a unit name, that name of course specifies the
- value's interpretation.
-
-### Duration format
-
-Implementations may wish to support a `getMilliseconds()` (and
-similar for other time units).
-
-This can use the general "units format" described above; bare
-numbers are taken to be in milliseconds already, while strings are
-parsed as a number plus an optional unit string.
-
-The supported unit strings for duration are case sensitive and
-must be lowercase. Exactly these strings are supported:
-
- - `ns`, `nano`, `nanos`, `nanosecond`, `nanoseconds`
- - `us`, `micro`, `micros`, `microsecond`, `microseconds`
- - `ms`, `milli`, `millis`, `millisecond`, `milliseconds`
- - `s`, `second`, `seconds`
- - `m`, `minute`, `minutes`
- - `h`, `hour`, `hours`
- - `d`, `day`, `days`
-
-### Period Format
-
-Similar to the `getDuration()` method, there is a `getPeriod()` method
-available for getting time units as a `java.time.Period`.
-
-This can use the general "units format" described above; bare
-numbers are taken to be in days, while strings are
-parsed as a number plus an optional unit string.
-
-The supported unit strings for period are case sensitive and
-must be lowercase. Exactly these strings are supported:
-
- - `d`, `day`, `days`
- - `w`, `week`, `weeks`
- - `m`, `mo`, `month`, `months` (note that if you are using `getTemporal()`
- which may return either a `java.time.Duration` or a `java.time.Period`
- you will want to use `mo` rather than `m` to prevent your unit being
- parsed as minutes)
- - `y`, `year`, `years`
-
-### Size in bytes format
-
-Implementations may wish to support a `getBytes()` returning a
-size in bytes.
-
-This can use the general "units format" described above; bare
-numbers are taken to be in bytes already, while strings are
-parsed as a number plus an optional unit string.
-
-The one-letter unit strings may be uppercase (note: duration units
-are always lowercase, so this convention is specific to size
-units).
-
-There is an unfortunate nightmare with size-in-bytes units, that
-they may be in powers or two or powers of ten. The approach
-defined by standards bodies appears to differ from common usage,
-such that following the standard leads to people being confused.
-Worse, common usage varies based on whether people are talking
-about RAM or disk sizes, and various existing operating systems
-and apps do all kinds of different things. See
-https://en.wikipedia.org/wiki/Binary_prefix#Deviation_between_powers_of_1024_and_powers_of_1000
-for examples. It appears impossible to sort this out without
-causing confusion for someone sometime.
-
-For single bytes, exactly these strings are supported:
-
- - `B`, `b`, `byte`, `bytes`
-
-For powers of ten, exactly these strings are supported:
-
- - `kB`, `kilobyte`, `kilobytes`
- - `MB`, `megabyte`, `megabytes`
- - `GB`, `gigabyte`, `gigabytes`
- - `TB`, `terabyte`, `terabytes`
- - `PB`, `petabyte`, `petabytes`
- - `EB`, `exabyte`, `exabytes`
- - `ZB`, `zettabyte`, `zettabytes`
- - `YB`, `yottabyte`, `yottabytes`
-
-For powers of two, exactly these strings are supported:
-
- - `K`, `k`, `Ki`, `KiB`, `kibibyte`, `kibibytes`
- - `M`, `m`, `Mi`, `MiB`, `mebibyte`, `mebibytes`
- - `G`, `g`, `Gi`, `GiB`, `gibibyte`, `gibibytes`
- - `T`, `t`, `Ti`, `TiB`, `tebibyte`, `tebibytes`
- - `P`, `p`, `Pi`, `PiB`, `pebibyte`, `pebibytes`
- - `E`, `e`, `Ei`, `EiB`, `exbibyte`, `exbibytes`
- - `Z`, `z`, `Zi`, `ZiB`, `zebibyte`, `zebibytes`
- - `Y`, `y`, `Yi`, `YiB`, `yobibyte`, `yobibytes`
-
-It's very unclear which units the single-character abbreviations
-("128K") should go with; some precedents such as `java -Xmx 2G`
-and the GNU tools such as `ls` map these to powers of two, so this
-spec copies that. You can certainly find examples of mapping these
-to powers of ten, though. If you don't like ambiguity, don't use
-the single-letter abbreviations.
-
-Note: any value in zetta/zebi or yotta/yobi will overflow a 64-bit
-integer, and of course large-enough values in any of the units may
-overflow. Most real-world APIs and apps will not support byte
-counts that overflow a 64-bit integer. The huge units are provided
-just to be complete but probably aren't useful in practice. At
-least not in 2014.
-
-### Config object merging and file merging
-
-It may be useful to offer a method to merge two objects. If such a
-method is provided, it should work as if the two objects were
-duplicate values for the same key in the same file. (See the
-section earlier on duplicate key handling.)
-
-As with duplicate keys, an intermediate non-object value "hides"
-earlier object values. So say you merge three objects in this
-order:
-
- - `{ a : { x : 1 } }` (first priority)
- - `{ a : 42 }` (fallback)
- - `{ a : { y : 2 } }` (another fallback)
-
-The result would be `{ a : { x : 1 } }`. The two objects are not
-merged because they are not "adjacent"; the merging is done in
-pairs, and when `42` is paired with `{ y : 2 }`, `42` simply wins
-and loses all information about what it overrode.
-
-But if you re-ordered like this:
-
- - `{ a : { x : 1 } }` (first priority)
- - `{ a : { y : 2 } }` (fallback)
- - `{ a : 42 }` (another fallback)
-
-Now the result would be `{ a : { x : 1, y : 2 } }` because the two
-objects are adjacent.
-
-This rule for merging objects loaded from different files is
-_exactly_ the same behavior as for merging duplicate fields in the
-same file. All merging works the same way.
-
-Needless to say, normally it's well-defined whether a config
-setting is supposed to be a number or an object. This kind of
-weird pathology where the two are mixed should not be happening.
-
-The one place where it matters, though, is that it allows you to
-"clear" an object and start over by setting it to null and then
-setting it back to a new object. So this behavior gives people a
-way to get rid of default fallback values they don't want.
-
-### Java properties mapping
-
-It may be useful to merge Java properties data with data loaded
-from JSON or HOCON. See the Java properties spec here:
-https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html#load-java.io.Reader-
-
-Java properties parse as a one-level map from string keys to
-string values.
-
-To convert to HOCON, first split each key on the `.` character,
-keeping any empty strings (including leading and trailing empty
-strings). Note that this is _very different_ from parsing a path
-expression.
-
-The key split on `.` is a series of path elements. So the
-properties key with just `.` is a path with two elements, both of
-them an empty string. `a.` is a path with two elements, `a` and
-empty string. (Java's `String.split()` does NOT do what you want
-for this.)
-
-It is impossible to represent a key with a `.` in it in a
-properties file. If a JSON/HOCON key has a `.` in it, which is
-possible if the key is quoted, then there is no way to refer to it
-as a Java property. It is not recommended to name HOCON keys with
-a `.` in them, since it would be confusing at best in any case.
-
-Once you have a path for each value, construct a tree of
-JSON-style objects with the string value of each property located
-at that value's path.
-
-Values from properties files are _always_ strings, even if they
-could be parsed as some other type. Implementations should do type
-conversion if an app asks for an integer, as described in an
-earlier section.
-
-When Java loads a properties file, unfortunately it does not
-preserve the order of the file. As a result, there is an
-intractable case where a single key needs to refer to both a
-parent object and a string value. For example, say the Java
-properties file has:
-
- a=hello
- a.b=world
-
-In this case, `a` needs to be both an object and a string value.
-The _object_ must always win in this case... the "object wins"
-rule throws out at most one value (the string) while "string wins"
-would throw out all values in the object. Unfortunately, when
-properties files are mapped to the JSON structure, there is no way
-to access these strings that conflict with objects.
-
-The usual rule in HOCON would be that the later assignment in the
-file wins, rather than "object wins"; but implementing that for
-Java properties would require implementing a custom Java
-properties parser, which is surely not worth it and wouldn't help
-with system properties anyway.
-
-### Conventional configuration files for JVM apps
-
-By convention, JVM apps have two parts to their configuration:
-
- - the _reference_ config is made up of all resources named
- `reference.conf` on the classpath, merged in the order they
- are returned by `ClassLoader.getResources()`; also, system
- property overrides are applied.
- - the _application_ config can be loaded from anywhere an
- application likes, but by default if the application doesn't
- provide a config it would be loaded from files
- `application.{conf,json,properties}` on the classpath and
- then system property overrides are applied.
- - the reference config may be different for different class
- loaders, since each jar may provide a `reference.conf`
- to go with the code in that jar.
- - a single JVM may have multiple application configs if
- it has multiple modules or contexts of some kind.
-
-The reference config for a given class loader should be merged and
-resolved first, and may be shared among all application configs in
-that class loader. Substitutions in the reference config are not
-affected by any application configs, because the reference config
-should be resolved by itself.
-
-The application config should then be loaded, have the reference
-config added as a fallback, and have substitutions resolved. This
-means the application config can refer to the reference config in
-its substitutions.
-
-### Conventional override by system properties
-
-For an application's config, Java system properties _override_
-settings found in the configuration file. This supports specifying
-config options on the command line.
-
-### Substitution fallback to environment variables
-
-Recall that if a substitution is not present (not even set to
-`null`) within a configuration tree, implementations may search
-for it from external sources. One such source could be environment
-variables.
-
-It's recommended that HOCON keys always use lowercase, because
-environment variables generally are capitalized. This avoids
-naming collisions between environment variables and configuration
-properties. (While on Windows getenv() is generally not
-case-sensitive, the lookup will be case sensitive all the way
-until the env variable fallback lookup is reached).
-
-See also the notes below on Windows and case sensitivity.
-
-An application can explicitly block looking up a substitution in
-the environment by setting a value in the configuration, with the
-same name as the environment variable. You could set `HOME : null`
-in your root object to avoid expanding `${HOME}` from the
-environment, for example.
-
-Environment variables are interpreted as follows:
-
- - env variables set to the empty string are kept as such (set to
- empty string, rather than undefined)
- - System.getenv throws SecurityException: treated as not present
- - encoding is handled by Java (System.getenv already returns
- a Unicode string)
- - environment variables always become a string value, though
- if an app asks for another type automatic type conversion
- would kick in
-
-### hyphen-separated vs. camelCase
-
-Config keys are encouraged to be `hyphen-separated` rather than
-`camelCase`.
-
-## Note on Java properties similarity
-
-You can write a HOCON file that looks much like a Java properties
-file, and many valid Java properties files will also parse as
-HOCON.
-
-However, HOCON is not a Java properties superset and the corner
-cases work like JSON, not like properties.
-
-Differences include but are probably not limited to:
-
- - certain characters that can be unquoted in properties files
- have to be placed in JSON-style double-quoted strings in HOCON
- - unquoted strings in HOCON do not support escape sequences
- - unquoted strings in HOCON do not preserve trailing whitespace
- - multi-line unquoted strings using backslash to continue the
- line are not allowed in HOCON
- - in properties files you can omit the value for a key and it's
- interpreted as an empty string, in HOCON you cannot omit the
- value
- - properties files support '!' as a comment character
- - HOCON allows comments on the same line as a key or value, while
- properties files only recognize comment characters if they
- occur as the first character on the line
- - HOCON interprets `${}` as a substitution
-
-## Note on Windows and case sensitivity of environment variables
-
-HOCON's lookup of environment variable values is always case sensitive, but
-Linux and Windows differ in their handling of case.
-
-Linux allows one to define multiple environment variables with the same
-name but with different case; so both "PATH" and "Path" may be defined
-simultaneously. HOCON's access to these environment variables on Linux
-is straightforward; ie just make sure you define all your vars with the required case.
-
-Windows is more confusing. Windows environment variables names may contain a
-mix of upper and lowercase characters, eg "Path", however Windows does not
-allow one to define multiple instances of the same name but differing in case.
-Whilst accessing env vars in Windows is case insensitive, accessing env vars in
-HOCON is case sensitive.
-So if you know that you HOCON needs "PATH" then you must ensure that
-the variable is defined as "PATH" rather than some other name such as
-"Path" or "path".
-However, Windows does not allow us to change the case of an existing env var; we can't
-simply redefine the var with an upper case name.
-The only way to ensure that your environment variables have the desired case
-is to first undefine all the env vars that you will depend on then redefine
-them with the required case.
-
-For example, the the ambient environment might have this definition ...
-
-```
-set Path=A;B;C
-```
-.. we just don't know. But if the HOCON needs "PATH", then the start script must
-take a precautionary approach and enforce the necessary case as follows ...
-
-```
-set OLDPATH=%PATH%
-set PATH=
-set PATH=%OLDPATH%
-
-%JAVA_HOME%/bin/java ....
-```
-
-You cannot know what ambient environment variables might exist in the ambient environment
-when your program is invoked, nor what case those definitions might have.
-Therefore the only safe thing to do is redefine all the vars you rely on as shown above.
diff --git a/seatunnel-config/README.md b/seatunnel-config/README.md
deleted file mode 100644
index 7e06f99..0000000
--- a/seatunnel-config/README.md
+++ /dev/null
@@ -1,930 +0,0 @@
-This project is a fork of https://github.com/lightbend/config, its mainly purpose is to solve these problems :
-
-* [Keep config item order in ConfigObject](https://github.com/lightbend/config/issues/365)
-
-* Change path token separator from `"."` to `"->""`.
-
-* Added `parseObjectForseatunnel()` to parse config objects in `input`, `filter`, `output` for seatunnel.
-
-* Change package name to avoid implementation conflict when using this code with the official typesafe config used by Apache Flink.
-
-
-If you want to do some test, please see:
-
-* Test Main Class: seatunnel-config/src/test/java/org/apache/seatunnel/config/CompleteTests.java
-
-* Config File Example: seatunnel-config/src/test/resources/seatunnel/variables.conf
-
-If you want to Package the jar:
-
-```
-git checkout garyelephant.fea.changed_package_name
-rm -rf ./target
-rm -rf ./config/target
-sbt package
-```
-
-then you can find `config-1.3.3.jar` in `./config/target/`
-
----
-
-Configuration library for JVM languages.
-
-[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.typesafe/config/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.typesafe/config)
-[![Build Status](https://travis-ci.org/lightbend/config.svg?branch=master)](https://travis-ci.org/lightbend/config)
-
-If you have questions or are working on a pull request or just
-curious, please feel welcome to join the chat room:
-[![Join chat https://gitter.im/lightbend/config](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/lightbend/config?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-## Overview
-
- - implemented in plain Java with no dependencies
- - supports files in three formats: Java properties, JSON, and a
- human-friendly JSON superset
- - merges multiple files across all formats
- - can load from files, URLs, or classpath
- - good support for "nesting" (treat any subtree of the config the
- same as the whole config)
- - users can override the config with Java system properties,
- `java -Dmyapp.foo.bar=10`
- - supports configuring an app, with its framework and libraries,
- all from a single file such as `application.conf`
- - parses duration and size settings, "512k" or "10 seconds"
- - converts types, so if you ask for a boolean and the value
- is the string "yes", or you ask for a float and the value is
- an int, it will figure it out.
- - JSON superset features:
- - comments
- - includes
- - substitutions (`"foo" : ${bar}`, `"foo" : Hello ${who}`)
- - properties-like notation (`a.b=c`)
- - less noisy, more lenient syntax
- - substitute environment variables (`logdir=${HOME}/logs`)
- - API based on immutable `Config` instances, for thread safety
- and easy reasoning about config transformations
- - extensive test coverage
-
-This library limits itself to config files. If you want to load
-config from a database or something, you would need to write some
-custom code. The library has nice support for merging
-configurations so if you build one from a custom source it's easy
-to merge it in.
-
-<!-- START doctoc generated TOC please keep comment here to allow auto update -->
-<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
-**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
-
-- [Essential Information](#essential-information)
- - [License](#license)
- - [Binary Releases](#binary-releases)
- - [Release Notes](#release-notes)
- - [API docs](#api-docs)
- - [Bugs and Patches](#bugs-and-patches)
- - [Build](#build)
-- [Using the Library](#using-the-library)
- - [API Example](#api-example)
- - [Longer Examples](#longer-examples)
- - [Immutability](#immutability)
- - [Schemas and Validation](#schemas-and-validation)
- - [Standard behavior](#standard-behavior)
- - [Note about resolving substitutions in `reference.conf` and `application.conf`](#note-about-resolving-substitutions-in-referenceconf-and-applicationconf)
- - [Merging config trees](#merging-config-trees)
- - [How to handle defaults](#how-to-handle-defaults)
- - [Understanding `Config` and `ConfigObject`](#understanding-config-and-configobject)
- - [ConfigBeanFactory](#configbeanfactory)
-- [Using HOCON, the JSON Superset](#using-hocon-the-json-superset)
- - [Features of HOCON](#features-of-hocon)
- - [Examples of HOCON](#examples-of-hocon)
- - [Uses of Substitutions](#uses-of-substitutions)
- - [Factor out common values](#factor-out-common-values)
- - [Inheritance](#inheritance)
- - [Optional system or env variable overrides](#optional-system-or-env-variable-overrides)
- - [Concatenation](#concatenation)
- - [`reference.conf` can't refer to `application.conf`](#referenceconf-cant-refer-to-applicationconf)
-- [Miscellaneous Notes](#miscellaneous-notes)
- - [Debugging Your Configuration](#debugging-your-configuration)
- - [Supports Java 8 and Later](#supports-java-8-and-later)
- - [Rationale for Supported File Formats](#rationale-for-supported-file-formats)
- - [Other APIs (Wrappers, Ports and Utilities)](#other-apis-wrappers-ports-and-utilities)
- - [Guice integration](#guice-integration)
- - [Java (yep!) wrappers for the Java library](#java-yep-wrappers-for-the-java-library)
- - [Scala wrappers for the Java library](#scala-wrappers-for-the-java-library)
- - [Clojure wrappers for the Java library](#clojure-wrappers-for-the-java-library)
- - [Kotlin wrappers for the Java library](#kotlin-wrappers-for-the-java-library)
- - [Scala port](#scala-port)
- - [Ruby port](#ruby-port)
- - [Puppet module](#puppet-module)
- - [Python port](#python-port)
- - [C++ port](#c-port)
- - [JavaScript port](#javascript-port)
- - [C# port](#c-port-1)
- - [Linting tool](#linting-tool)
-
-<!-- END doctoc generated TOC please keep comment here to allow auto update -->
-
-## Essential Information
-
-### Binary Releases
-
-Version 1.2.1 and earlier were built for Java 6, while newer
-versions (1.3.0 and above) will be built for Java 8.
-
-You can find published releases on Maven Central.
-
- <dependency>
- <groupId>com.typesafe</groupId>
- <artifactId>config</artifactId>
- <version>1.3.2</version>
- </dependency>
-
-sbt dependency:
-
- libraryDependencies += "com.typesafe" % "config" % "1.3.2"
-
-Link for direct download if you don't use a dependency manager:
-
- - https://mvnrepository.com/artifact/com.typesafe/config
-
-### Release Notes
-
-Please see NEWS.md in this directory,
-https://github.com/lightbend/config/blob/master/NEWS.md
-
-### API docs
-
- - Online: https://lightbend.github.io/config/latest/api/
- - also published in jar form
- - consider reading this README first for an intro
- - for questions about the `.conf` file format, read
- [HOCON.md](https://github.com/lightbend/config/blob/master/HOCON.md)
- in this directory
-
-### Bugs and Patches
-
-Report bugs to the GitHub issue tracker. Send patches as pull
-requests on GitHub.
-
-Before we can accept pull requests, you will need to agree to the
-Typesafe Contributor License Agreement online, using your GitHub
-account - it takes 30 seconds. You can do this at
-https://www.lightbend.com/contribute/cla
-
-Please see
-[CONTRIBUTING](https://github.com/lightbend/config/blob/master/CONTRIBUTING.md)
-for more including how to make a release.
-
-### Build
-
-The build uses sbt and the tests are written in Scala; however,
-the library itself is plain Java and the published jar has no
-Scala dependency.
-
-## Using the Library
-
-### API Example
- import com.typesafe.config.ConfigFactory
-
- Config conf = ConfigFactory.load();
- int bar1 = conf.getInt("foo.bar");
- Config foo = conf.getConfig("foo");
- int bar2 = foo.getInt("bar");
-
-### Longer Examples
-
-See the examples in the `examples/` [directory](https://github.com/lightbend/config/tree/master/examples).
-
-You can run these from the sbt console with the commands `project
-config-simple-app-java` and then `run`.
-
-In brief, as shown in the examples:
-
- - libraries should use a `Config` instance provided by the app,
- if any, and use `ConfigFactory.load()` if no special `Config`
- is provided. Libraries should put their defaults in a
- `reference.conf` on the classpath.
- - apps can create a `Config` however they want
- (`ConfigFactory.load()` is easiest and least-surprising), then
- provide it to their libraries. A `Config` can be created with
- the parser methods in `ConfigFactory` or built up from any file
- format or data source you like with the methods in
- `ConfigValueFactory`.
-
-### Immutability
-
-Objects are immutable, so methods on `Config` which transform the
-configuration return a new `Config`. Other types such as
-`ConfigParseOptions`, `ConfigResolveOptions`, `ConfigObject`,
-etc. are also immutable. See the
-[API docs](https://lightbend.github.io/config/latest/api/) for
-details of course.
-
-### Schemas and Validation
-
-There isn't a schema language or anything like that. However, two
-suggested tools are:
-
- - use the
- [checkValid() method](https://lightbend.github.io/config/latest/api/com/typesafe/config/Config.html#checkValid-com.typesafe.config.Config-java.lang.String...-)
- - access your config through a Settings class with a field for
- each setting, and instantiate it on startup (immediately
- throwing an exception if any settings are missing)
-
-In Scala, a Settings class might look like:
-
- class Settings(config: Config) {
-
- // validate vs. reference.conf
- config.checkValid(ConfigFactory.defaultReference(), "simple-lib")
-
- // non-lazy fields, we want all exceptions at construct time
- val foo = config.getString("simple-lib.foo")
- val bar = config.getInt("simple-lib.bar")
- }
-
-See the examples/ directory for a full compilable program using
-this pattern.
-
-### Standard behavior
-
-The convenience method `ConfigFactory.load()` loads the following
-(first-listed are higher priority):
-
- - system properties
- - `application.conf` (all resources on classpath with this name)
- - `application.json` (all resources on classpath with this name)
- - `application.properties` (all resources on classpath with this
- name)
- - `reference.conf` (all resources on classpath with this name)
-
-The idea is that libraries and frameworks should ship with a
-`reference.conf` in their jar. Applications should provide an
-`application.conf`, or if they want to create multiple
-configurations in a single JVM, they could use
-`ConfigFactory.load("myapp")` to load their own `myapp.conf`.
-(Applications _can_ provide a `reference.conf` also if they want,
-but you may not find it necessary to separate it from
-`application.conf`.)
-
-Libraries and frameworks should default to `ConfigFactory.load()`
-if the application does not provide a custom `Config` object. This
-way, libraries will see configuration from `application.conf` and
-users can configure the whole app, with its libraries, in a single
-`application.conf` file.
-
-Libraries and frameworks should also allow the application to
-provide a custom `Config` object to be used instead of the
-default, in case the application needs multiple configurations in
-one JVM or wants to load extra config files from somewhere. The
-library examples in `examples/` show how to accept a custom config
-while defaulting to `ConfigFactory.load()`.
-
-For applications using `application.{conf,json,properties}`,
-system properties can be used to force a different config source
-(e.g. from command line `-Dconfig.file=path/to/config-file`):
-
- - `config.resource` specifies a resource name - not a
- basename, i.e. `application.conf` not `application`
- - `config.file` specifies a filesystem path, again
- it should include the extension, not be a basename
- - `config.url` specifies a URL
-
-These system properties specify a _replacement_ for
-`application.{conf,json,properties}`, not an addition. They only
-affect apps using the default `ConfigFactory.load()`
-configuration. In the replacement config file, you can use
-`include "application"` to include the original default config
-file; after the include statement you could go on to override
-certain settings.
-
-If you set `config.resource`, `config.file`, or `config.url`
-on-the-fly from inside your program (for example with
-`System.setProperty()`), be aware that `ConfigFactory` has some
-internal caches and may not see new values for system
-properties. Use `ConfigFactory.invalidateCaches()` to force-reload
-system properties.
-
-#### Note about resolving substitutions in `reference.conf` and `application.conf`
-
-The substitution syntax `${foo.bar}` will be resolved
-twice. First, all the `reference.conf` files are merged and then
-the result gets resolved. Second, all the `application.conf` are
-layered over the `reference.conf` and the result of that gets
-resolved again.
-
-The implication of this is that the `reference.conf` stack has to
-be self-contained; you can't leave an undefined value `${foo.bar}`
-to be provided by `application.conf`, or refer to `${foo.bar}` in
-a way that you want to allow `application.conf` to
-override. However, `application.conf` can refer to a `${foo.bar}`
-in `reference.conf`.
-
-This can be frustrating at times, but possible workarounds
-include:
-
- * putting an `application.conf` in a library jar, alongside the
-`reference.conf`, with values intended for later resolution.
- * putting some logic in code instead of building up values in the
- config itself.
-
-### Merging config trees
-
-Any two Config objects can be merged with an associative operation
-called `withFallback`, like `merged = firstConfig.withFallback(secondConfig)`.
-
-The `withFallback` operation is used inside the library to merge
-duplicate keys in the same file and to merge multiple files.
-`ConfigFactory.load()` uses it to stack system properties over
-`application.conf` over `reference.conf`.
-
-You can also use `withFallback` to merge in some hardcoded values,
-or to "lift" a subtree up to the root of the configuration; say
-you have something like:
-
- foo=42
- dev.foo=57
- prod.foo=10
-
-Then you could code something like:
-
- Config devConfig = originalConfig
- .getConfig("dev")
- .withFallback(originalConfig)
-
-There are lots of ways to use `withFallback`.
-
-### How to handle defaults
-
-Many other configuration APIs allow you to provide a default to
-the getter methods, like this:
-
- boolean getBoolean(String path, boolean fallback)
-
-Here, if the path has no setting, the fallback would be
-returned. An API could also return `null` for unset values, so you
-would check for `null`:
-
- // returns null on unset, check for null and fall back
- Boolean getBoolean(String path)
-
-The methods on the `Config` interface do NOT do this, for two
-major reasons:
-
- 1. If you use a config setting in two places, the default
- fallback value gets cut-and-pasted and typically out of
- sync. This can result in Very Evil Bugs.
- 2. If the getter returns `null` (or `None`, in Scala) then every
- time you get a setting you have to write handling code for
- `null`/`None` and that code will almost always just throw an
- exception. Perhaps more commonly, people forget to check for
- `null` at all, so missing settings result in
- `NullPointerException`.
-
-For most situations, failure to have a setting is simply a bug to fix
-(in either code or the deployment environment). Therefore, if a
-setting is unset, by default the getters on the `Config` interface
-throw an exception.
-
-If you want to allow a setting to be missing from
-`application.conf` in a particular case, then here are some
-options:
-
- 1. Set it in a `reference.conf` included in your library or
- application jar, so there's a default value.
- 2. Use the `Config.hasPath()` method to check in advance whether
- the path exists (rather than checking for `null`/`None` after as
- you might in other APIs).
- 3. Catch and handle `ConfigException.Missing`. NOTE: using an
- exception for control flow like this is much slower than using
- `Config.hasPath()`; the JVM has to do a lot of work to throw
- an exception.
- 4. In your initialization code, generate a `Config` with your
- defaults in it (using something like `ConfigFactory.parseMap()`)
- then fold that default config into your loaded config using
- `withFallback()`, and use the combined config in your
- program. "Inlining" your reference config in the code like this
- is probably less convenient than using a `reference.conf` file,
- but there may be reasons to do it.
- 5. Use `Config.root()` to get the `ConfigObject` for the
- `Config`; `ConfigObject` implements `java.util.Map<String,?>` and
- the `get()` method on `Map` returns null for missing keys. See
- the API docs for more detail on `Config` vs. `ConfigObject`.
- 6. Set the setting to `null` in `reference.conf`, then use
- `Config.getIsNull` and `Config.hasPathOrNull` to handle `null`
- in a special way while still throwing an exception if the setting
- is entirely absent.
-
-The *recommended* path (for most cases, in most apps) is that you
-require all settings to be present in either `reference.conf` or
-`application.conf` and allow `ConfigException.Missing` to be
-thrown if they are not. That's the design intent of the `Config`
-API design.
-
-Consider the "Settings class" pattern with `checkValid()` to
-verify that you have all settings when you initialize the
-app. See the [Schemas and Validation](#schemas-and-validation)
-section of this README for more details on this pattern.
-
-**If you do need a setting to be optional**: checking `hasPath()` in
-advance should be the same amount of code (in Java) as checking
-for `null` afterward, without the risk of `NullPointerException`
-when you forget. In Scala, you could write an enrichment class
-like this to use the idiomatic `Option` syntax:
-
-```scala
-implicit class RichConfig(val underlying: Config) extends AnyVal {
- def getOptionalBoolean(path: String): Option[Boolean] = if (underlying.hasPath(path)) {
- Some(underlying.getBoolean(path))
- } else {
- None
- }
-}
-```
-
-Since this library is a Java library it doesn't come with that out
-of the box, of course.
-
-It is understood that sometimes defaults in code make sense. For
-example, if your configuration lets users invent new sections, you
-may not have all paths up front and may be unable to set up
-defaults in `reference.conf` for dynamic paths. The design intent
-of `Config` isn't to *prohibit* inline defaults, but simply to
-recognize that it seems to be the 10% case (rather than the 90%
-case). Even in cases where dynamic defaults are needed, you may
-find that using `withFallback()` to build a complete
-nothing-missing `Config` in one central place in your code keeps
-things tidy.
-
-Whatever you do, please remember not to cut-and-paste default
-values into multiple places in your code. You have been warned!
-:-)
-
-### Understanding `Config` and `ConfigObject`
-
-To read and modify configuration, you'll use the
-[Config](https://lightbend.github.io/config/latest/api/com/typesafe/config/Config.html)
-interface. A `Config` looks at a JSON-equivalent data structure as
-a one-level map from paths to values. So if your JSON looks like
-this:
-
-```
- "foo" : {
- "bar" : 42
- "baz" : 43
- }
-```
-
-Using the `Config` interface, you could write
-`conf.getInt("foo.bar")`. The `foo.bar` string is called a _path
-expression_
-([HOCON.md](https://github.com/lightbend/config/blob/master/HOCON.md)
-has the syntax details for these expressions). Iterating over this
-`Config`, you would get two entries; `"foo.bar" : 42` and
-`"foo.baz" : 43`. When iterating a `Config` you will not find
-nested `Config` (because everything gets flattened into one
-level).
-
-When looking at a JSON tree as a `Config`, `null` values are
-treated as if they were missing. Iterating over a `Config` will
-skip `null` values.
-
-You can also look at a `Config` in the way most JSON APIs would,
-through the
-[ConfigObject](https://lightbend.github.io/config/latest/api/com/typesafe/config/ConfigObject.html)
-interface. This interface represents an object node in the JSON
-tree. `ConfigObject` instances come in multi-level trees, and the
-keys do not have any syntax (they are just strings, not path
-expressions). Iterating over the above example as a
-`ConfigObject`, you would get one entry `"foo" : { "bar" : 42,
-"baz" : 43 }`, where the value at `"foo"` is another nested
-`ConfigObject`.
-
-In `ConfigObject`, `null` values are visible (distinct from
-missing values), just as they are in JSON.
-
-`ConfigObject` is a subtype of [ConfigValue](https://lightbend.github.io/config/latest/api/com/typesafe/config/ConfigValue.html), where the other
-subtypes are the other JSON types (list, string, number, boolean, null).
-
-`Config` and `ConfigObject` are two ways to look at the same
-internal data structure, and you can convert between them for free
-using
-[Config.root()](https://lightbend.github.io/config/latest/api/com/typesafe/config/Config.html#root--)
-and
-[ConfigObject.toConfig()](https://lightbend.github.io/config/latest/api/com/typesafe/config/ConfigObject.html#toConfig--).
-
-### ConfigBeanFactory
-
-As of version 1.3.0, if you have a Java object that follows
-JavaBean conventions (zero-args constructor, getters and setters),
-you can automatically initialize it from a `Config`.
-
-Use
-`ConfigBeanFactory.create(config.getConfig("subtree-that-matches-bean"),
-MyBean.class)` to do this.
-
-Creating a bean from a `Config` automatically validates that the
-config matches the bean's implied schema. Bean fields can be
-primitive types, typed lists such as `List<Integer>`,
-`java.time.Duration`, `ConfigMemorySize`, or even a raw `Config`,
-`ConfigObject`, or `ConfigValue` (if you'd like to deal with a
-particular value manually).
-
-## Using HOCON, the JSON Superset
-
-The JSON superset is called "Human-Optimized Config Object
-Notation" or HOCON, and files use the suffix `.conf`. See
-[HOCON.md](https://github.com/lightbend/config/blob/master/HOCON.md)
-in this directory for more detail.
-
-After processing a `.conf` file, the result is always just a JSON
-tree that you could have written (less conveniently) in JSON.
-
-### Features of HOCON
-
- - Comments, with `#` or `//`
- - Allow omitting the `{}` around a root object
- - Allow `=` as a synonym for `:`
- - Allow omitting the `=` or `:` before a `{` so
- `foo { a : 42 }`
- - Allow omitting commas as long as there's a newline
- - Allow trailing commas after last element in objects and arrays
- - Allow unquoted strings for keys and values
- - Unquoted keys can use dot-notation for nested objects,
- `foo.bar=42` means `foo { bar : 42 }`
- - Duplicate keys are allowed; later values override earlier,
- except for object-valued keys where the two objects are merged
- recursively
- - `include` feature merges root object in another file into
- current object, so `foo { include "bar.json" }` merges keys in
- `bar.json` into the object `foo`
- - include with no file extension includes any of `.conf`,
- `.json`, `.properties`
- - you can include files, URLs, or classpath resources; use
- `include url("http://example.com")` or `file()` or
- `classpath()` syntax to force the type, or use just `include
- "whatever"` to have the library do what you probably mean
- (Note: `url()`/`file()`/`classpath()` syntax is not supported
- in Play/Akka 2.0, only in later releases.)
- - substitutions `foo : ${a.b}` sets key `foo` to the same value
- as the `b` field in the `a` object
- - substitutions concatenate into unquoted strings, `foo : the
- quick ${colors.fox} jumped`
- - substitutions fall back to environment variables if they don't
- resolve in the config itself, so `${HOME}` would work as you
- expect. Also, most configs have system properties merged in so
- you could use `${user.home}`.
- - substitutions normally cause an error if unresolved, but
- there is a syntax `${?a.b}` to permit them to be missing.
- - `+=` syntax to append elements to arrays, `path += "/bin"`
- - multi-line strings with triple quotes as in Python or Scala
-
-### Examples of HOCON
-
-All of these are valid HOCON.
-
-Start with valid JSON:
-
- {
- "foo" : {
- "bar" : 10,
- "baz" : 12
- }
- }
-
-Drop root braces:
-
- "foo" : {
- "bar" : 10,
- "baz" : 12
- }
-
-Drop quotes:
-
- foo : {
- bar : 10,
- baz : 12
- }
-
-Use `=` and omit it before `{`:
-
- foo {
- bar = 10,
- baz = 12
- }
-
-Remove commas:
-
- foo {
- bar = 10
- baz = 12
- }
-
-Use dotted notation for unquoted keys:
-
- foo.bar=10
- foo.baz=12
-
-Put the dotted-notation fields on a single line:
-
- foo.bar=10, foo.baz=12
-
-The syntax is well-defined (including handling of whitespace and
-escaping). But it handles many reasonable ways you might want to
-format the file.
-
-Note that while you can write HOCON that looks a lot like a Java
-properties file (and many properties files will parse as HOCON),
-the details of escaping, whitespace handling, comments, and so
-forth are more like JSON. The spec (see HOCON.md in this
-directory) has some more detailed notes on this topic.
-
-### Uses of Substitutions
-
-The `${foo.bar}` substitution feature lets you avoid cut-and-paste
-in some nice ways.
-
-#### Factor out common values
-
-This is the obvious use,
-
- standard-timeout = 10ms
- foo.timeout = ${standard-timeout}
- bar.timeout = ${standard-timeout}
-
-#### Inheritance
-
-If you duplicate a field with an object value, then the objects
-are merged with last-one-wins. So:
-
- foo = { a : 42, c : 5 }
- foo = { b : 43, c : 6 }
-
-means the same as:
-
- foo = { a : 42, b : 43, c : 6 }
-
-You can take advantage of this for "inheritance":
-
- data-center-generic = { cluster-size = 6 }
- data-center-east = ${data-center-generic}
- data-center-east = { name = "east" }
- data-center-west = ${data-center-generic}
- data-center-west = { name = "west", cluster-size = 8 }
-
-Using `include` statements you could split this across multiple
-files, too.
-
-If you put two objects next to each other (close brace of the first
-on the same line with open brace of the second), they are merged, so
-a shorter way to write the above "inheritance" example would be:
-
- data-center-generic = { cluster-size = 6 }
- data-center-east = ${data-center-generic} { name = "east" }
- data-center-west = ${data-center-generic} { name = "west", cluster-size = 8 }
-
-#### Optional system or env variable overrides
-
-In default uses of the library, exact-match system properties
-already override the corresponding config properties. However,
-you can add your own overrides, or allow environment variables to
-override, using the `${?foo}` substitution syntax.
-
- basedir = "/whatever/whatever"
- basedir = ${?FORCED_BASEDIR}
-
-Here, the override field `basedir = ${?FORCED_BASEDIR}` simply
-vanishes if there's no value for `FORCED_BASEDIR`, but if you set
-an environment variable `FORCED_BASEDIR` for example, it would be
-used.
-
-A natural extension of this idea is to support several different
-environment variable names or system property names, if you aren't
-sure which one will exist in the target environment.
-
-Object fields and array elements with a `${?foo}` substitution
-value just disappear if the substitution is not found:
-
- // this array could have one or two elements
- path = [ "a", ${?OPTIONAL_A} ]
-
-### Concatenation
-
-Values _on the same line_ are concatenated (for strings and
-arrays) or merged (for objects).
-
-This is why unquoted strings work, here the number `42` and the
-string `foo` are concatenated into a string `42 foo`:
-
- key : 42 foo
-
-When concatenating values into a string, leading and trailing
-whitespace is stripped but whitespace between values is kept.
-
-Unquoted strings also support substitutions of course:
-
- tasks-url : ${base-url}/tasks
-
-A concatenation can refer to earlier values of the same field:
-
- path : "/bin"
- path : ${path}":/usr/bin"
-
-Arrays can be concatenated as well:
-
- path : [ "/bin" ]
- path : ${path} [ "/usr/bin" ]
-
-There is a shorthand for appending to arrays:
-
- // equivalent to: path = ${?path} [ "/usr/bin" ]
- path += "/usr/bin"
-
-To prepend or insert into an array, there is no shorthand.
-
-When objects are "concatenated," they are merged, so object
-concatenation is just a shorthand for defining the same object
-twice. The long way (mentioned earlier) is:
-
- data-center-generic = { cluster-size = 6 }
- data-center-east = ${data-center-generic}
- data-center-east = { name = "east" }
-
-The concatenation-style shortcut is:
-
- data-center-generic = { cluster-size = 6 }
- data-center-east = ${data-center-generic} { name = "east" }
-
-When concatenating objects and arrays, newlines are allowed
-_inside_ each object or array, but not between them.
-
-Non-newline whitespace is never a field or element separator. So
-`[ 1 2 3 4 ]` is an array with one unquoted string element
-`"1 2 3 4"`. To get an array of four numbers you need either commas or
-newlines separating the numbers.
-
-See the spec for full details on concatenation.
-
-Note: Play/Akka 2.0 have an earlier version that supports string
-concatenation, but not object/array concatenation. `+=` does not
-work in Play/Akka 2.0 either. Post-2.0 versions support these
-features.
-
-### `reference.conf` can't refer to `application.conf`
-
-Please see <a
-href="#note-about-resolving-substitutions-in-referenceconf-and-applicationconf">this
-earlier section</a>; all `reference.conf` have substitutions
-resolved first, without `application.conf` in the stack, so the
-reference stack has to be self-contained.
-
-## Miscellaneous Notes
-
-### Debugging Your Configuration
-
-If you have trouble with your configuration, some useful tips.
-
- - Set the Java system property `-Dconfig.trace=loads` to get
- output on stderr describing each file that is loaded.
- Note: this feature is not included in the older version in
- Play/Akka 2.0.
- - Use `myConfig.root().render()` to get a `Config` printed out as a
- string with comments showing where each value came from.
-
-### Supports Java 8 and Later
-
-Currently the library is maintained against Java 8, but
-version 1.2.1 and earlier will work with Java 6.
-
-Please use 1.2.1 if you need Java 6 support, though some people
-have expressed interest in a branch off of 1.3.x supporting
-Java 7. If you want to work on that branch you might bring it up
-on [chat](https://gitter.im/lightbend/config). We can release a
-jar for Java 7 if someone(s) steps up to maintain the branch. The
-master branch does not use Java 8 "gratuitously" but some APIs
-that use Java 8 types will need to be removed.
-
-### Rationale for Supported File Formats
-
-(For the curious.)
-
-The three file formats each have advantages.
-
- - Java `.properties`:
- - Java standard, built in to JVM
- - Supported by many tools such as IDEs
- - JSON:
- - easy to generate programmatically
- - well-defined and standard
- - bad for human maintenance, with no way to write comments,
- and no mechanisms to avoid duplication of similar config
- sections
- - HOCON/`.conf`:
- - nice for humans to read, type, and maintain, with more
- lenient syntax
- - built-in tools to avoid cut-and-paste
- - ways to refer to the system environment, such as system
- properties and environment variables
-
-The idea would be to use JSON if you're writing a script to spit
-out config, and use HOCON if you're maintaining config by hand.
-If you're doing both, then mix the two.
-
-Two alternatives to HOCON syntax could be:
-
- - YAML is also a JSON superset and has a mechanism for adding
- custom types, so the include statements in HOCON could become
- a custom type tag like `!include`, and substitutions in HOCON
- could become a custom tag such as `!subst`, for example. The
- result is somewhat clunky to write, but would have the same
- in-memory representation as the HOCON approach.
- - Put a syntax inside JSON strings, so you might write something
- like `"$include" : "filename"` or allow `"foo" : "${bar}"`.
- This is a way to tunnel new syntax through a JSON parser, but
- other than the implementation benefit (using a standard JSON
- parser), it doesn't really work. It's a bad syntax for human
- maintenance, and it's not valid JSON anymore because properly
- interpreting it requires treating some valid JSON strings as
- something other than plain strings. A better approach is to
- allow mixing true JSON files into the config but also support
- a nicer format.
-
-### Other APIs (Wrappers, Ports and Utilities)
-
-This may not be comprehensive - if you'd like to add mention of
-your wrapper, just send a pull request for this README. We would
-love to know what you're doing with this library or with the HOCON
-format.
-
-#### Guice integration
- * Typesafe Config Guice https://github.com/racc/typesafeconfig-guice
-
-#### Java (yep!) wrappers for the Java library
-
- * tscfg https://github.com/carueda/tscfg
-
-#### Scala wrappers for the Java library
-
- * Ficus https://github.com/ceedubs/ficus
- * configz https://github.com/arosien/configz
- * configs https://github.com/kxbmap/configs
- Â * config-annotation https://github.com/zhongl/config-annotation
- * PureConfig https://github.com/pureconfig/pureconfig
- * Simple Scala Config https://github.com/ElderResearch/ssc
- * konfig https://github.com/vpon/konfig
- * ScalaConfig https://github.com/andr83/scalaconfig
- * static-config https://github.com/Krever/static-config
- * validated-config https://github.com/carlpulley/validated-config
- * Cedi Config https://github.com/ccadllc/cedi-config
- * Cfg https://github.com/carueda/cfg
- * circe-config https://github.com/circe/circe-config
-
-#### Clojure wrappers for the Java library
-
- * beamly-core.config https://github.com/beamly/beamly-core.config
-
-#### Kotlin wrappers for the Java library
- * config4k https://github.com/config4k/config4k
-
-#### Scala port
-
- * SHocon https://github.com/unicredit/shocon (work with both Scala and Scala.Js)
-
-#### Ruby port
-
- * https://github.com/puppetlabs/ruby-hocon
-
-#### Puppet module
-
- * Manage your HOCON configuration files with Puppet!: https://forge.puppetlabs.com/puppetlabs/hocon
-
-#### Python port
-
- * pyhocon https://github.com/chimpler/pyhocon
-
-#### C++ port
-
- * https://github.com/puppetlabs/cpp-hocon
-
-#### JavaScript port
-
- * https://github.com/yellowblood/hocon-js (missing features, under development)
-
-#### C# port
-
- * https://github.com/akkadotnet/HOCON
-
-#### Linting tool
-
- * A web based linting tool http://www.hoconlint.com/
-
-# Maintanance notes
-
-## License
-
-The license is Apache 2.0, see LICENSE-2.0.txt.
-
-## Maintained by
-
-This project is maintained mostly by [@havocp](https://github.com/havocp) and [@akka-team](https://github.com/orgs/lightbend/teams/akka-team/members).
-
-Feel free to ping above maintainers for code review or discussions. Pull requests are very welcome–thanks in advance!
diff --git a/seatunnel-config/pom.xml b/seatunnel-config/pom.xml
index a0488ba..3874d71 100644
--- a/seatunnel-config/pom.xml
+++ b/seatunnel-config/pom.xml
@@ -35,6 +35,94 @@
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<skip.pmd.check>true</skip.pmd.check>
+ <seatunnel.shade.package>org.apache.seatunnel.shade</seatunnel.shade.package>
</properties>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.typesafe</groupId>
+ <artifactId>config</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+
+ <finalName>${project.artifactId}-${project.version}</finalName>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <configuration>
+ <minimizeJar>true</minimizeJar>
+ <createSourcesJar>true</createSourcesJar>
+ <shadeSourcesContent>true</shadeSourcesContent>
+ <shadedArtifactAttached>false</shadedArtifactAttached>
+ <filters>
+ <filter>
+ <artifact>com.typesafe:config</artifact>
+ <includes>
+ <include>**</include>
+ </includes>
+ <excludes>
+ <exclude>META-INF/MANIFEST.MF</exclude>
+ <exclude>META-INF/NOTICE</exclude>
+ <exclude>com/typesafe/config/ConfigParseOptions.class</exclude>
+ <exclude>com/typesafe/config/impl/ConfigParser.class</exclude>
+ <exclude>com/typesafe/config/impl/ConfigNodePath.class</exclude>
+ <exclude>com/typesafe/config/impl/PathParser.class</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ <relocations>
+ <relocation>
+ <pattern>com.typesafe.config</pattern>
+ <shadedPattern>${seatunnel.shade.package}.com.typesafe.config</shadedPattern>
+ </relocation>
+ </relocations>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer"/>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer"/>
+ </transformers>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>compile</id>
+ <phase>package</phase>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${basedir}/target/${project.artifactId}-${project.version}.jar</file>
+ <type>jar</type>
+ <classifier>optional</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
</project>
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigParseOptions.java b/seatunnel-config/src/main/java/com/typesafe/config/ConfigParseOptions.java
similarity index 90%
rename from seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigParseOptions.java
rename to seatunnel-config/src/main/java/com/typesafe/config/ConfigParseOptions.java
index 5e6904c..a0895c6 100644
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigParseOptions.java
+++ b/seatunnel-config/src/main/java/com/typesafe/config/ConfigParseOptions.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.seatunnel.config;
+package com.typesafe.config;
/**
* A set of options related to parsing.
@@ -76,9 +76,10 @@ public final class ConfigParseOptions {
public ConfigParseOptions setSyntax(ConfigSyntax syntax) {
if (this.syntax == syntax) {
return this;
- }
- return new ConfigParseOptions(syntax, this.originDescription, this.allowMissing,
+ } else {
+ return new ConfigParseOptions(syntax, this.originDescription, this.allowMissing,
this.includer, this.classLoader);
+ }
}
/**
@@ -104,11 +105,13 @@ public final class ConfigParseOptions {
// findbugs complains about == here but is wrong, do not "fix"
if (this.originDescription == originDescription) {
return this;
- } else if (this.originDescription != null && originDescription != null && this.originDescription.equals(originDescription)) {
+ } else if (this.originDescription != null && originDescription != null
+ && this.originDescription.equals(originDescription)) {
return this;
- }
- return new ConfigParseOptions(this.syntax, originDescription, this.allowMissing,
+ } else {
+ return new ConfigParseOptions(this.syntax, originDescription, this.allowMissing,
this.includer, this.classLoader);
+ }
}
/**
@@ -126,8 +129,9 @@ public final class ConfigParseOptions {
ConfigParseOptions withFallbackOriginDescription(String originDescription) {
if (this.originDescription == null) {
return setOriginDescription(originDescription);
+ } else {
+ return this;
}
- return this;
}
/**
@@ -142,9 +146,10 @@ public final class ConfigParseOptions {
public ConfigParseOptions setAllowMissing(boolean allowMissing) {
if (this.allowMissing == allowMissing) {
return this;
- }
- return new ConfigParseOptions(this.syntax, this.originDescription, allowMissing,
+ } else {
+ return new ConfigParseOptions(this.syntax, this.originDescription, allowMissing,
this.includer, this.classLoader);
+ }
}
/**
@@ -166,9 +171,10 @@ public final class ConfigParseOptions {
public ConfigParseOptions setIncluder(ConfigIncluder includer) {
if (this.includer == includer) {
return this;
- }
- return new ConfigParseOptions(this.syntax, this.originDescription, this.allowMissing,
+ } else {
+ return new ConfigParseOptions(this.syntax, this.originDescription, this.allowMissing,
includer, this.classLoader);
+ }
}
/**
@@ -188,8 +194,9 @@ public final class ConfigParseOptions {
return this;
} else if (this.includer != null) {
return setIncluder(includer.withFallback(this.includer));
+ } else {
+ return setIncluder(includer);
}
- return setIncluder(includer);
}
/**
@@ -208,8 +215,9 @@ public final class ConfigParseOptions {
return this;
} else if (this.includer != null) {
return setIncluder(this.includer.withFallback(includer));
+ } else {
+ return setIncluder(includer);
}
- return setIncluder(includer);
}
/**
@@ -232,9 +240,10 @@ public final class ConfigParseOptions {
public ConfigParseOptions setClassLoader(ClassLoader loader) {
if (this.classLoader == loader) {
return this;
- }
- return new ConfigParseOptions(this.syntax, this.originDescription, this.allowMissing,
+ } else {
+ return new ConfigParseOptions(this.syntax, this.originDescription, this.allowMissing,
this.includer, loader);
+ }
}
/**
@@ -247,7 +256,8 @@ public final class ConfigParseOptions {
public ClassLoader getClassLoader() {
if (this.classLoader == null) {
return Thread.currentThread().getContextClassLoader();
+ } else {
+ return this.classLoader;
}
- return this.classLoader;
}
}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigNodePath.java b/seatunnel-config/src/main/java/com/typesafe/config/impl/ConfigNodePath.java
similarity index 86%
rename from seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigNodePath.java
rename to seatunnel-config/src/main/java/com/typesafe/config/impl/ConfigNodePath.java
index e5486b3..609e4f8 100644
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigNodePath.java
+++ b/seatunnel-config/src/main/java/com/typesafe/config/impl/ConfigNodePath.java
@@ -15,10 +15,10 @@
* limitations under the License.
*/
-package org.apache.seatunnel.config.impl;
+package com.typesafe.config.impl;
-import org.apache.seatunnel.config.ConfigException;
-import org.apache.seatunnel.config.ConfigParseOptions;
+import com.typesafe.config.ConfigException;
+import com.typesafe.config.ConfigParseOptions;
import java.util.ArrayList;
import java.util.Collection;
@@ -46,7 +46,7 @@ final class ConfigNodePath extends AbstractConfigNode {
ArrayList<Token> tokensCopy = new ArrayList<Token>(tokens);
for (int i = 0; i < tokensCopy.size(); i++) {
if (Tokens.isUnquotedText(tokensCopy.get(i)) &&
- tokensCopy.get(i).tokenText().equals(ConfigParseOptions.PATH_TOKEN_SEPARATOR)) {
+ tokensCopy.get(i).tokenText().equals(ConfigParseOptions.PATH_TOKEN_SEPARATOR)) {
periodCount++;
}
@@ -61,7 +61,7 @@ final class ConfigNodePath extends AbstractConfigNode {
ArrayList<Token> tokensCopy = new ArrayList<Token>(tokens);
for (int i = 0; i < tokensCopy.size(); i++) {
if (Tokens.isUnquotedText(tokensCopy.get(i)) &&
- tokensCopy.get(i).tokenText().equals(ConfigParseOptions.PATH_TOKEN_SEPARATOR)) {
+ tokensCopy.get(i).tokenText().equals(ConfigParseOptions.PATH_TOKEN_SEPARATOR)) {
return new ConfigNodePath(path.subPath(0, 1), tokensCopy.subList(0, i));
}
}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigParser.java b/seatunnel-config/src/main/java/com/typesafe/config/impl/ConfigParser.java
similarity index 87%
rename from seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigParser.java
rename to seatunnel-config/src/main/java/com/typesafe/config/impl/ConfigParser.java
index 3e0e7b2..02c21a1 100644
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigParser.java
+++ b/seatunnel-config/src/main/java/com/typesafe/config/impl/ConfigParser.java
@@ -15,15 +15,14 @@
* limitations under the License.
*/
-package org.apache.seatunnel.config.impl;
+package com.typesafe.config.impl;
-import org.apache.seatunnel.config.ConfigException;
-import org.apache.seatunnel.config.ConfigException.BugOrBroken;
-import org.apache.seatunnel.config.ConfigIncludeContext;
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigParseOptions;
-import org.apache.seatunnel.config.ConfigSyntax;
-import org.apache.seatunnel.config.ConfigValueFactory;
+import com.typesafe.config.ConfigException;
+import com.typesafe.config.ConfigIncludeContext;
+import com.typesafe.config.ConfigOrigin;
+import com.typesafe.config.ConfigParseOptions;
+import com.typesafe.config.ConfigSyntax;
+import com.typesafe.config.ConfigValueFactory;
import java.io.File;
import java.net.MalformedURLException;
@@ -41,7 +40,7 @@ final class ConfigParser {
ConfigOrigin origin, ConfigParseOptions options,
ConfigIncludeContext includeContext) {
ParseContext context = new ParseContext(options.getSyntax(), origin, document,
- SimpleIncluder.makeFull(options.getIncluder()), includeContext);
+ SimpleIncluder.makeFull(options.getIncluder()), includeContext);
return context.parse();
}
@@ -77,7 +76,7 @@ final class ConfigParser {
private AbstractConfigValue parseConcatenation(ConfigNodeConcatenation n) {
// this trick is not done in JSON
if (flavor == ConfigSyntax.JSON) {
- throw new BugOrBroken("Found a concatenation node in JSON");
+ throw new ConfigException.BugOrBroken("Found a concatenation node in JSON");
}
List<AbstractConfigValue> values = new ArrayList<AbstractConfigValue>();
@@ -109,8 +108,9 @@ final class ConfigParser {
// pathStack has top of stack at front
if (pathStack.isEmpty()) {
throw new ConfigException.BugOrBroken("Bug in parser; tried to get current path when at root");
+ } else {
+ return new Path(pathStack.descendingIterator());
}
- return new Path(pathStack.descendingIterator());
}
private AbstractConfigValue parseValue(AbstractConfigNodeValue n, List<String> comments) {
@@ -125,13 +125,13 @@ final class ConfigParser {
Path path = pathStack.peekFirst();
if (path != null
- && ("input".equals(path.first())
- || "filter".equals(path.first())
- || "output".equals(path.first())
- || "source".equals(path.first())
- || "transform".equals(path.first())
- || "sink".equals(path.first()))) {
- v = parseObjectForSeatunnel((ConfigNodeObject) n);
+ && ("input".equals(path.first())
+ || "filter".equals(path.first())
+ || "output".equals(path.first())
+ || "source".equals(path.first())
+ || "transform".equals(path.first())
+ || "sink".equals(path.first()))) {
+ v = parseObjectForWaterdrop((ConfigNodeObject) n);
} else {
v = parseObject((ConfigNodeObject) n);
}
@@ -181,11 +181,11 @@ final class ConfigParser {
ListIterator<String> i = keys.listIterator(keys.size());
String deepest = i.previous();
AbstractConfigObject o = new SimpleConfigObject(value.origin().withComments(null),
- Collections.<String, AbstractConfigValue>singletonMap(
- deepest, value));
+ Collections.<String, AbstractConfigValue>singletonMap(
+ deepest, value));
while (i.hasPrevious()) {
Map<String, AbstractConfigValue> m = Collections.<String, AbstractConfigValue>singletonMap(
- i.previous(), o);
+ i.previous(), o);
o = new SimpleConfigObject(value.origin().withComments(null), m);
}
@@ -210,7 +210,7 @@ final class ConfigParser {
case FILE:
obj = (AbstractConfigObject) includer.includeFile(cic,
- new File(n.name()));
+ new File(n.name()));
break;
case CLASSPATH:
@@ -219,7 +219,7 @@ final class ConfigParser {
case HEURISTIC:
obj = (AbstractConfigObject) includer
- .include(cic, n.name());
+ .include(cic, n.name());
break;
default:
@@ -231,8 +231,8 @@ final class ConfigParser {
// See https://github.com/lightbend/config/issues/160
if (arrayCount > 0 && obj.resolveStatus() != ResolveStatus.RESOLVED) {
throw parseError("Due to current limitations of the config parser, when an include statement is nested inside a list value, "
- + "${} substitutions inside the included file cannot be resolved correctly. Either move the include outside of the list value or "
- + "remove the ${} statements from the included file.");
+ + "${} substitutions inside the included file cannot be resolved correctly. Either move the include outside of the list value or "
+ + "remove the ${} statements from the included file.");
}
if (!pathStack.isEmpty()) {
@@ -251,7 +251,7 @@ final class ConfigParser {
}
}
- private SimpleConfigList parseObjectForSeatunnel(ConfigNodeObject n) {
+ private SimpleConfigList parseObjectForWaterdrop(ConfigNodeObject n) {
Map<String, AbstractConfigValue> values = new LinkedHashMap<String, AbstractConfigValue>();
List<AbstractConfigValue> valuesList = new ArrayList<AbstractConfigValue>();
@@ -265,8 +265,7 @@ final class ConfigParser {
if (node instanceof ConfigNodeComment) {
lastWasNewline = false;
comments.add(((ConfigNodeComment) node).commentText());
- } else if (node instanceof ConfigNodeSingleToken
- && Tokens.isNewline(((ConfigNodeSingleToken) node).token())) {
+ } else if (node instanceof ConfigNodeSingleToken && Tokens.isNewline(((ConfigNodeSingleToken) node).token())) {
lineNumber++;
if (lastWasNewline) {
// Drop all comments if there was a blank line and start a new comment block
@@ -290,8 +289,8 @@ final class ConfigParser {
// https://github.com/lightbend/config/issues/160
if (arrayCount > 0) {
throw parseError("Due to current limitations of the config parser, += does not work nested inside a list. "
- + "+= expands to a ${} substitution and the path in ${} cannot currently refer to list elements. "
- + "You might be able to move the += outside of the list and then refer to it from inside the list with ${}.");
+ + "+= expands to a ${} substitution and the path in ${} cannot currently refer to list elements. "
+ + "You might be able to move the += outside of the list and then refer to it from inside the list with ${}.");
}
// because we will put it in an array after the fact so
@@ -313,9 +312,9 @@ final class ConfigParser {
List<AbstractConfigValue> concat = new ArrayList<AbstractConfigValue>(2);
AbstractConfigValue previousRef = new ConfigReference(newValue.origin(),
- new SubstitutionExpression(fullCurrentPath(), true /* optional */));
+ new SubstitutionExpression(fullCurrentPath(), true /* optional */));
AbstractConfigValue list = new SimpleConfigList(newValue.origin(),
- Collections.singletonList(newValue));
+ Collections.singletonList(newValue));
concat.add(previousRef);
concat.add(list);
newValue = ConfigConcatenation.concatenate(concat);
@@ -328,7 +327,7 @@ final class ConfigParser {
if (nodes.get(i) instanceof ConfigNodeComment) {
ConfigNodeComment comment = (ConfigNodeComment) nodes.get(i);
newValue = newValue.withOrigin(newValue.origin().appendComments(
- Collections.singletonList(comment.commentText())));
+ Collections.singletonList(comment.commentText())));
break;
} else if (nodes.get(i) instanceof ConfigNodeSingleToken) {
ConfigNodeSingleToken curr = (ConfigNodeSingleToken) nodes.get(i);
@@ -361,11 +360,11 @@ final class ConfigParser {
} else {
if (flavor == ConfigSyntax.JSON) {
throw new ConfigException.BugOrBroken(
- "somehow got multi-element path in JSON mode");
+ "somehow got multi-element path in JSON mode");
}
AbstractConfigObject obj = createValueUnderPath(
- remaining, newValue);
+ remaining, newValue);
Map<String, String> m = Collections.singletonMap("plugin_name", key);
obj = obj.withFallback(ConfigValueFactory.fromMap(m));
@@ -391,8 +390,7 @@ final class ConfigParser {
if (node instanceof ConfigNodeComment) {
lastWasNewline = false;
comments.add(((ConfigNodeComment) node).commentText());
- } else if (node instanceof ConfigNodeSingleToken
- && Tokens.isNewline(((ConfigNodeSingleToken) node).token())) {
+ } else if (node instanceof ConfigNodeSingleToken && Tokens.isNewline(((ConfigNodeSingleToken) node).token())) {
lineNumber++;
if (lastWasNewline) {
// Drop all comments if there was a blank line and start a new comment block
@@ -416,8 +414,8 @@ final class ConfigParser {
// https://github.com/lightbend/config/issues/160
if (arrayCount > 0) {
throw parseError("Due to current limitations of the config parser, += does not work nested inside a list. "
- + "+= expands to a ${} substitution and the path in ${} cannot currently refer to list elements. "
- + "You might be able to move the += outside of the list and then refer to it from inside the list with ${}.");
+ + "+= expands to a ${} substitution and the path in ${} cannot currently refer to list elements. "
+ + "You might be able to move the += outside of the list and then refer to it from inside the list with ${}.");
}
// because we will put it in an array after the fact so
@@ -439,9 +437,9 @@ final class ConfigParser {
List<AbstractConfigValue> concat = new ArrayList<AbstractConfigValue>(2);
AbstractConfigValue previousRef = new ConfigReference(newValue.origin(),
- new SubstitutionExpression(fullCurrentPath(), true /* optional */));
+ new SubstitutionExpression(fullCurrentPath(), true /* optional */));
AbstractConfigValue list = new SimpleConfigList(newValue.origin(),
- Collections.singletonList(newValue));
+ Collections.singletonList(newValue));
concat.add(previousRef);
concat.add(list);
newValue = ConfigConcatenation.concatenate(concat);
@@ -454,7 +452,7 @@ final class ConfigParser {
if (nodes.get(i) instanceof ConfigNodeComment) {
ConfigNodeComment comment = (ConfigNodeComment) nodes.get(i);
newValue = newValue.withOrigin(newValue.origin().appendComments(
- Collections.singletonList(comment.commentText())));
+ Collections.singletonList(comment.commentText())));
break;
} else if (nodes.get(i) instanceof ConfigNodeSingleToken) {
ConfigNodeSingleToken curr = (ConfigNodeSingleToken) nodes.get(i);
@@ -487,8 +485,9 @@ final class ConfigParser {
if (flavor == ConfigSyntax.JSON) {
throw parseError("JSON does not allow duplicate fields: '"
- + key + "' was already seen at "
- + existing.origin().description());
+ + key
+ + "' was already seen at "
+ + existing.origin().description());
} else {
newValue = newValue.withFallback(existing);
}
@@ -497,11 +496,11 @@ final class ConfigParser {
} else {
if (flavor == ConfigSyntax.JSON) {
throw new ConfigException.BugOrBroken(
- "somehow got multi-element path in JSON mode");
+ "somehow got multi-element path in JSON mode");
}
AbstractConfigObject obj = createValueUnderPath(
- remaining, newValue);
+ remaining, newValue);
AbstractConfigValue existing = values.get(key);
if (existing != null) {
obj = obj.withFallback(existing);
@@ -529,8 +528,7 @@ final class ConfigParser {
if (node instanceof ConfigNodeComment) {
comments.add(((ConfigNodeComment) node).commentText());
lastWasNewLine = false;
- } else if (node instanceof ConfigNodeSingleToken
- && Tokens.isNewline(((ConfigNodeSingleToken) node).token())) {
+ } else if (node instanceof ConfigNodeSingleToken && Tokens.isNewline(((ConfigNodeSingleToken) node).token())) {
lineNumber++;
if (lastWasNewLine && v == null) {
comments.clear();
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/PathParser.java b/seatunnel-config/src/main/java/com/typesafe/config/impl/PathParser.java
similarity index 89%
rename from seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/PathParser.java
rename to seatunnel-config/src/main/java/com/typesafe/config/impl/PathParser.java
index 9d4d283..c23feab 100644
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/PathParser.java
+++ b/seatunnel-config/src/main/java/com/typesafe/config/impl/PathParser.java
@@ -15,13 +15,13 @@
* limitations under the License.
*/
-package org.apache.seatunnel.config.impl;
+package com.typesafe.config.impl;
-import org.apache.seatunnel.config.ConfigException.BadPath;
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigParseOptions;
-import org.apache.seatunnel.config.ConfigSyntax;
-import org.apache.seatunnel.config.ConfigValueType;
+import com.typesafe.config.ConfigException;
+import com.typesafe.config.ConfigOrigin;
+import com.typesafe.config.ConfigParseOptions;
+import com.typesafe.config.ConfigSyntax;
+import com.typesafe.config.ConfigValueType;
import java.io.StringReader;
import java.util.ArrayList;
@@ -58,7 +58,7 @@ final class PathParser {
try {
Iterator<Token> tokens = Tokenizer.tokenize(API_ORIGIN, reader,
- flavor);
+ flavor);
tokens.next(); // drop START
return parsePathNodeExpression(tokens, API_ORIGIN, path, flavor);
} finally {
@@ -76,7 +76,7 @@ final class PathParser {
try {
Iterator<Token> tokens = Tokenizer.tokenize(API_ORIGIN, reader,
- ConfigSyntax.CONF);
+ ConfigSyntax.CONF);
tokens.next(); // drop START
return parsePathExpression(tokens, API_ORIGIN, path);
} finally {
@@ -116,8 +116,8 @@ final class PathParser {
buf.add(new Element("", false));
if (!expression.hasNext()) {
- throw new BadPath(origin, originalText,
- "Expecting a field name or path here, but got nothing");
+ throw new ConfigException.BadPath(origin, originalText,
+ "Expecting a field name or path here, but got nothing");
}
while (expression.hasNext()) {
@@ -174,11 +174,12 @@ final class PathParser {
}
text = Tokens.getUnquotedText(t);
} else {
- throw new BadPath(
- origin,
- originalText,
- "Token not allowed in path expression: "
- + t + " (you can double-quote this token if you really want it here)");
+ throw new ConfigException.BadPath(
+ origin,
+ originalText,
+ "Token not allowed in path expression: "
+ + t
+ + " (you can double-quote this token if you really want it here)");
}
addPathText(buf, false, text);
@@ -188,12 +189,13 @@ final class PathParser {
PathBuilder pb = new PathBuilder();
for (Element e : buf) {
if (e.sb.length() == 0 && !e.canBeEmpty) {
- throw new BadPath(
- origin,
- originalText,
- "path has a leading, trailing, or two adjacent period '.' (use quoted \"\" empty string if you want an empty element)");
+ throw new ConfigException.BadPath(
+ origin,
+ originalText,
+ "path has a leading, trailing, or two adjacent period '.' (use quoted \"\" empty string if you want an empty element)");
+ } else {
+ pb.appendKey(e.sb.toString());
}
- pb.appendKey(e.sb.toString());
}
return pb.result();
@@ -277,8 +279,9 @@ final class PathParser {
return true;
}
continue;
+ } else {
+ return true;
}
- return true;
}
if (lastWasDot) {
@@ -299,9 +302,10 @@ final class PathParser {
if (splitAt < 0) {
Path withOneMoreElement = new Path(s.substring(0, end), tail);
return withOneMoreElement;
+ } else {
+ Path withOneMoreElement = new Path(s.substring(splitAt + ConfigParseOptions.PATH_TOKEN_SEPARATOR.length(), end), tail);
+ return fastPathBuild(withOneMoreElement, s, splitAt);
}
- Path withOneMoreElement = new Path(s.substring(splitAt + ConfigParseOptions.PATH_TOKEN_SEPARATOR.length(), end), tail);
- return fastPathBuild(withOneMoreElement, s, splitAt);
}
// do something much faster than the full parser if
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/Config.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/Config.java
deleted file mode 100644
index db5a6c1..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/Config.java
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import java.time.Duration;
-import java.time.Period;
-import java.time.temporal.TemporalAmount;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/**
- * An immutable map from config paths to config values. Paths are dot-separated
- * expressions such as <code>foo.bar.baz</code>. Values are as in JSON
- * (booleans, strings, numbers, lists, or objects), represented by
- * {@link ConfigValue} instances. Values accessed through the
- * <code>Config</code> interface are never null.
- *
- * <p>
- * {@code Config} is an immutable object and thus safe to use from multiple
- * threads. There's never a need for "defensive copies."
- *
- * <p>
- * Fundamental operations on a {@code Config} include getting configuration
- * values, <em>resolving</em> substitutions with {@link Config#resolve()}, and
- * merging configs using {@link Config#withFallback(ConfigMergeable)}.
- *
- * <p>
- * All operations return a new immutable {@code Config} rather than modifying
- * the original instance.
- *
- * <p>
- * <strong>Examples</strong>
- *
- * <p>
- * You can find an example app and library <a
- * href="https://github.com/lightbend/config/tree/master/examples">on
- * GitHub</a>. Also be sure to read the <a
- * href="package-summary.html#package_description">package overview</a> which
- * describes the big picture as shown in those examples.
- *
- * <p>
- * <strong>Paths, keys, and Config vs. ConfigObject</strong>
- *
- * <p>
- * <code>Config</code> is a view onto a tree of {@link ConfigObject}; the
- * corresponding object tree can be found through {@link Config#root()}.
- * <code>ConfigObject</code> is a map from config <em>keys</em>, rather than
- * paths, to config values. Think of <code>ConfigObject</code> as a JSON object
- * and <code>Config</code> as a configuration API.
- *
- * <p>
- * The API tries to consistently use the terms "key" and "path." A key is a key
- * in a JSON object; it's just a string that's the key in a map. A "path" is a
- * parseable expression with a syntax and it refers to a series of keys. Path
- * expressions are described in the <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">spec for
- * Human-Optimized Config Object Notation</a>. In brief, a path is
- * period-separated so "a.b.c" looks for key c in object b in object a in the
- * root object. Sometimes double quotes are needed around special characters in
- * path expressions.
- *
- * <p>
- * The API for a {@code Config} is in terms of path expressions, while the API
- * for a {@code ConfigObject} is in terms of keys. Conceptually, {@code Config}
- * is a one-level map from <em>paths</em> to values, while a
- * {@code ConfigObject} is a tree of nested maps from <em>keys</em> to values.
- *
- * <p>
- * Use {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath} to convert
- * between path expressions and individual path elements (keys).
- *
- * <p>
- * Another difference between {@code Config} and {@code ConfigObject} is that
- * conceptually, {@code ConfigValue}s with a {@link ConfigValue#valueType()
- * valueType()} of {@link ConfigValueType#NULL NULL} exist in a
- * {@code ConfigObject}, while a {@code Config} treats null values as if they
- * were missing. (With the exception of two methods: {@link Config#hasPathOrNull}
- * and {@link Config#getIsNull} let you detect <code>null</code> values.)
- *
- * <p>
- * <strong>Getting configuration values</strong>
- *
- * <p>
- * The "getters" on a {@code Config} all work in the same way. They never return
- * null, nor do they return a {@code ConfigValue} with
- * {@link ConfigValue#valueType() valueType()} of {@link ConfigValueType#NULL
- * NULL}. Instead, they throw {@link ConfigException.Missing} if the value is
- * completely absent or set to null. If the value is set to null, a subtype of
- * {@code ConfigException.Missing} called {@link ConfigException.Null} will be
- * thrown. {@link ConfigException.WrongType} will be thrown anytime you ask for
- * a type and the value has an incompatible type. Reasonable type conversions
- * are performed for you though.
- *
- * <p>
- * <strong>Iteration</strong>
- *
- * <p>
- * If you want to iterate over the contents of a {@code Config}, you can get its
- * {@code ConfigObject} with {@link #root()}, and then iterate over the
- * {@code ConfigObject} (which implements <code>java.util.Map</code>). Or, you
- * can use {@link #entrySet()} which recurses the object tree for you and builds
- * up a <code>Set</code> of all path-value pairs where the value is not null.
- *
- * <p>
- * <strong>Resolving substitutions</strong>
- *
- * <p>
- * <em>Substitutions</em> are the <code>${foo.bar}</code> syntax in config
- * files, described in the <a href=
- * "https://github.com/lightbend/config/blob/master/HOCON.md#substitutions"
- * >specification</a>. Resolving substitutions replaces these references with real
- * values.
- *
- * <p>
- * Before using a {@code Config} it's necessary to call {@link Config#resolve()}
- * to handle substitutions (though {@link ConfigFactory#load()} and similar
- * methods will do the resolve for you already).
- *
- * <p>
- * <strong>Merging</strong>
- *
- * <p>
- * The full <code>Config</code> for your application can be constructed using
- * the associative operation {@link Config#withFallback(ConfigMergeable)}. If
- * you use {@link ConfigFactory#load()} (recommended), it merges system
- * properties over the top of <code>application.conf</code> over the top of
- * <code>reference.conf</code>, using <code>withFallback</code>. You can add in
- * additional sources of configuration in the same way (usually, custom layers
- * should go either just above or just below <code>application.conf</code>,
- * keeping <code>reference.conf</code> at the bottom and system properties at
- * the top).
- *
- * <p>
- * <strong>Serialization</strong>
- *
- * <p>
- * Convert a <code>Config</code> to a JSON or HOCON string by calling
- * {@link ConfigObject#render()} on the root object,
- * <code>myConfig.root().render()</code>. There's also a variant
- * {@link ConfigObject#render(ConfigRenderOptions)} which allows you to control
- * the format of the rendered string. (See {@link ConfigRenderOptions}.) Note
- * that <code>Config</code> does not remember the formatting of the original
- * file, so if you load, modify, and re-save a config file, it will be
- * substantially reformatted.
- *
- * <p>
- * As an alternative to {@link ConfigObject#render()}, the
- * <code>toString()</code> method produces a debug-output-oriented
- * representation (which is not valid JSON).
- *
- * <p>
- * Java serialization is supported as well for <code>Config</code> and all
- * subtypes of <code>ConfigValue</code>.
- *
- * <p>
- * <strong>This is an interface but don't implement it yourself</strong>
- *
- * <p>
- * <em>Do not implement {@code Config}</em>; it should only be implemented by
- * the config library. Arbitrary implementations will not work because the
- * library internals assume a specific concrete implementation. Also, this
- * interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface Config extends ConfigMergeable {
- /**
- * Gets the {@code Config} as a tree of {@link ConfigObject}. This is a
- * constant-time operation (it is not proportional to the number of values
- * in the {@code Config}).
- *
- * @return the root object in the configuration
- */
- ConfigObject root();
-
- /**
- * Gets the origin of the {@code Config}, which may be a file, or a file
- * with a line number, or just a descriptive phrase.
- *
- * @return the origin of the {@code Config} for use in error messages
- */
- ConfigOrigin origin();
-
- @Override
- Config withFallback(ConfigMergeable other);
-
- /**
- * Returns a replacement config with all substitutions (the
- * <code>${foo.bar}</code> syntax, see <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
- * spec</a>) resolved. Substitutions are looked up using this
- * <code>Config</code> as the root object, that is, a substitution
- * <code>${foo.bar}</code> will be replaced with the result of
- * <code>getValue("foo.bar")</code>.
- *
- * <p>
- * This method uses {@link ConfigResolveOptions#defaults()}, there is
- * another variant {@link Config#resolve(ConfigResolveOptions)} which lets
- * you specify non-default options.
- *
- * <p>
- * A given {@link Config} must be resolved before using it to retrieve
- * config values, but ideally should be resolved one time for your entire
- * stack of fallbacks (see {@link Config#withFallback}). Otherwise, some
- * substitutions that could have resolved with all fallbacks available may
- * not resolve, which will be potentially confusing for your application's
- * users.
- *
- * <p>
- * <code>resolve()</code> should be invoked on root config objects, rather
- * than on a subtree (a subtree is the result of something like
- * <code>config.getConfig("foo")</code>). The problem with
- * <code>resolve()</code> on a subtree is that substitutions are relative to
- * the root of the config and the subtree will have no way to get values
- * from the root. For example, if you did
- * <code>config.getConfig("foo").resolve()</code> on the below config file,
- * it would not work:
- *
- * <pre>
- * common-value = 10
- * foo {
- * whatever = ${common-value}
- * }
- * </pre>
- *
- * <p>
- * Many methods on {@link ConfigFactory} such as
- * {@link ConfigFactory#load()} automatically resolve the loaded
- * <code>Config</code> on the loaded stack of config files.
- *
- * <p>
- * Resolving an already-resolved config is a harmless no-op, but again, it
- * is best to resolve an entire stack of fallbacks (such as all your config
- * files combined) rather than resolving each one individually.
- *
- * @return an immutable object with substitutions resolved
- * @throws ConfigException.UnresolvedSubstitution if any substitutions refer to nonexistent paths
- * @throws ConfigException some other config exception if there are other problems
- */
- Config resolve();
-
- /**
- * Like {@link Config#resolve()} but allows you to specify non-default
- * options.
- *
- * @param options resolve options
- * @return the resolved <code>Config</code> (may be only partially resolved if options are set to allow unresolved)
- */
- Config resolve(ConfigResolveOptions options);
-
- /**
- * Checks whether the config is completely resolved. After a successful call
- * to {@link Config#resolve()} it will be completely resolved, but after
- * calling {@link Config#resolve(ConfigResolveOptions)} with
- * <code>allowUnresolved</code> set in the options, it may or may not be
- * completely resolved. A newly-loaded config may or may not be completely
- * resolved depending on whether there were substitutions present in the
- * file.
- *
- * @return true if there are no unresolved substitutions remaining in this
- * configuration.
- * @since 1.2.0
- */
- boolean isResolved();
-
- /**
- * Like {@link Config#resolve()} except that substitution values are looked
- * up in the given source, rather than in this instance. This is a
- * special-purpose method which doesn't make sense to use in most cases;
- * it's only needed if you're constructing some sort of app-specific custom
- * approach to configuration. The more usual approach if you have a source
- * of substitution values would be to merge that source into your config
- * stack using {@link Config#withFallback} and then resolve.
- * <p>
- * Note that this method does NOT look in this instance for substitution
- * values. If you want to do that, you could either merge this instance into
- * your value source using {@link Config#withFallback}, or you could resolve
- * multiple times with multiple sources (using
- * {@link ConfigResolveOptions#setAllowUnresolved(boolean)} so the partial
- * resolves don't fail).
- *
- * @param source configuration to pull values from
- * @return an immutable object with substitutions resolved
- * @throws ConfigException.UnresolvedSubstitution if any substitutions refer to paths which are not in the
- * source
- * @throws ConfigException some other config exception if there are other problems
- * @since 1.2.0
- */
- Config resolveWith(Config source);
-
- /**
- * Like {@link Config#resolveWith(Config)} but allows you to specify
- * non-default options.
- *
- * @param source source configuration to pull values from
- * @param options resolve options
- * @return the resolved <code>Config</code> (may be only partially resolved
- * if options are set to allow unresolved)
- * @since 1.2.0
- */
- Config resolveWith(Config source, ConfigResolveOptions options);
-
- /**
- * Validates this config against a reference config, throwing an exception
- * if it is invalid. The purpose of this method is to "fail early" with a
- * comprehensive list of problems; in general, anything this method can find
- * would be detected later when trying to use the config, but it's often
- * more user-friendly to fail right away when loading the config.
- *
- * <p>
- * Using this method is always optional, since you can "fail late" instead.
- *
- * <p>
- * You must restrict validation to paths you "own" (those whose meaning are
- * defined by your code module). If you validate globally, you may trigger
- * errors about paths that happen to be in the config but have nothing to do
- * with your module. It's best to allow the modules owning those paths to
- * validate them. Also, if every module validates only its own stuff, there
- * isn't as much redundant work being done.
- *
- * <p>
- * If no paths are specified in <code>checkValid()</code>'s parameter list,
- * validation is for the entire config.
- *
- * <p>
- * If you specify paths that are not in the reference config, those paths
- * are ignored. (There's nothing to validate.)
- *
- * <p>
- * Here's what validation involves:
- *
- * <ul>
- * <li>All paths found in the reference config must be present in this
- * config or an exception will be thrown.
- * <li>
- * Some changes in type from the reference config to this config will cause
- * an exception to be thrown. Not all potential type problems are detected,
- * in particular it's assumed that strings are compatible with everything
- * except objects and lists. This is because string types are often "really"
- * some other type (system properties always start out as strings, or a
- * string like "5ms" could be used with {@link #getMilliseconds}). Also,
- * it's allowed to set any type to null or override null with any type.
- * <li>
- * Any unresolved substitutions in this config will cause a validation
- * failure; both the reference config and this config should be resolved
- * before validation. If the reference config is unresolved, it's a bug in
- * the caller of this method.
- * </ul>
- *
- * <p>
- * If you want to allow a certain setting to have a flexible type (or
- * otherwise want validation to be looser for some settings), you could
- * either remove the problematic setting from the reference config provided
- * to this method, or you could intercept the validation exception and
- * screen out certain problems. Of course, this will only work if all other
- * callers of this method are careful to restrict validation to their own
- * paths, as they should be.
- *
- * <p>
- * If validation fails, the thrown exception contains a list of all problems
- * found. See {@link ConfigException.ValidationFailed#problems}. The
- * exception's <code>getMessage()</code> will have all the problems
- * concatenated into one huge string, as well.
- *
- * <p>
- * Again, <code>checkValid()</code> can't guess every domain-specific way a
- * setting can be invalid, so some problems may arise later when attempting
- * to use the config. <code>checkValid()</code> is limited to reporting
- * generic, but common, problems such as missing settings and blatant type
- * incompatibilities.
- *
- * @param reference a reference configuration
- * @param restrictToPaths only validate values underneath these paths that your code
- * module owns and understands
- * @throws ConfigException.ValidationFailed if there are any validation issues
- * @throws ConfigException.NotResolved if this config is not resolved
- * @throws ConfigException.BugOrBroken if the reference config is unresolved or caller otherwise
- * misuses the API
- */
- void checkValid(Config reference, String... restrictToPaths);
-
- /**
- * Checks whether a value is present and non-null at the given path. This
- * differs in two ways from {@code Map.containsKey()} as implemented by
- * {@link ConfigObject}: it looks for a path expression, not a key; and it
- * returns false for null values, while {@code containsKey()} returns true
- * indicating that the object contains a null value for the key.
- *
- * <p>
- * If a path exists according to {@link #hasPath(String)}, then
- * {@link #getValue(String)} will never throw an exception. However, the
- * typed getters, such as {@link #getInt(String)}, will still throw if the
- * value is not convertible to the requested type.
- *
- * <p>
- * Note that path expressions have a syntax and sometimes require quoting
- * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
- *
- * @param path the path expression
- * @return true if a non-null value is present at the path
- * @throws ConfigException.BadPath if the path expression is invalid
- */
- boolean hasPath(String path);
-
- /**
- * Checks whether a value is present at the given path, even
- * if the value is null. Most of the getters on
- * <code>Config</code> will throw if you try to get a null
- * value, so if you plan to call {@link #getValue(String)},
- * {@link #getInt(String)}, or another getter you may want to
- * use plain {@link #hasPath(String)} rather than this method.
- *
- * <p>
- * To handle all three cases (unset, null, and a non-null value)
- * the code might look like:
- * <pre><code>
- * if (config.hasPathOrNull(path)) {
- * if (config.getIsNull(path)) {
- * // handle null setting
- * } else {
- * // get and use non-null setting
- * }
- * } else {
- * // handle entirely unset path
- * }
- * </code></pre>
- *
- * <p> However, the usual thing is to allow entirely unset
- * paths to be a bug that throws an exception (because you set
- * a default in your <code>reference.conf</code>), so in that
- * case it's OK to call {@link #getIsNull(String)} without
- * checking <code>hasPathOrNull</code> first.
- *
- * <p>
- * Note that path expressions have a syntax and sometimes require quoting
- * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
- *
- * @param path the path expression
- * @return true if a value is present at the path, even if the value is null
- * @throws ConfigException.BadPath if the path expression is invalid
- */
- boolean hasPathOrNull(String path);
-
- /**
- * Returns true if the {@code Config}'s root object contains no key-value
- * pairs.
- *
- * @return true if the configuration is empty
- */
- boolean isEmpty();
-
- /**
- * Returns the set of path-value pairs, excluding any null values, found by
- * recursing {@link #root() the root object}. Note that this is very
- * different from <code>root().entrySet()</code> which returns the set of
- * immediate-child keys in the root object and includes null values.
- * <p>
- * Entries contain <em>path expressions</em> meaning there may be quoting
- * and escaping involved. Parse path expressions with
- * {@link ConfigUtil#splitPath}.
- * <p>
- * Because a <code>Config</code> is conceptually a single-level map from
- * paths to values, there will not be any {@link ConfigObject} values in the
- * entries (that is, all entries represent leaf nodes). Use
- * {@link ConfigObject} rather than <code>Config</code> if you want a tree.
- * (OK, this is a slight lie: <code>Config</code> entries may contain
- * {@link ConfigList} and the lists may contain objects. But no objects are
- * directly included as entry values.)
- *
- * @return set of paths with non-null values, built up by recursing the
- * entire tree of {@link ConfigObject} and creating an entry for
- * each leaf value.
- */
- Set<Map.Entry<String, ConfigValue>> entrySet();
-
- /**
- * Checks whether a value is set to null at the given path,
- * but throws an exception if the value is entirely
- * unset. This method will not throw if {@link
- * #hasPathOrNull(String)} returned true for the same path, so
- * to avoid any possible exception check
- * <code>hasPathOrNull()</code> first. However, an exception
- * for unset paths will usually be the right thing (because a
- * <code>reference.conf</code> should exist that has the path
- * set, the path should never be unset unless something is
- * broken).
- *
- * <p>
- * Note that path expressions have a syntax and sometimes require quoting
- * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
- *
- * @param path the path expression
- * @return true if the value exists and is null, false if it
- * exists and is not null
- * @throws ConfigException.BadPath if the path expression is invalid
- * @throws ConfigException.Missing if value is not set at all
- */
- boolean getIsNull(String path);
-
- /**
- * @param path path expression
- * @return the boolean value at the requested path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to boolean
- */
- boolean getBoolean(String path);
-
- /**
- * @param path path expression
- * @return the numeric value at the requested path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a number
- */
- Number getNumber(String path);
-
- /**
- * Gets the integer at the given path. If the value at the
- * path has a fractional (floating point) component, it
- * will be discarded and only the integer part will be
- * returned (it works like a "narrowing primitive conversion"
- * in the Java language specification).
- *
- * @param path path expression
- * @return the 32-bit integer value at the requested path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to an int (for example it is out
- * of range, or it's a boolean value)
- */
- int getInt(String path);
-
- /**
- * Gets the long integer at the given path. If the value at
- * the path has a fractional (floating point) component, it
- * will be discarded and only the integer part will be
- * returned (it works like a "narrowing primitive conversion"
- * in the Java language specification).
- *
- * @param path path expression
- * @return the 64-bit long value at the requested path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a long
- */
- long getLong(String path);
-
- /**
- * @param path path expression
- * @return the floating-point value at the requested path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a double
- */
- double getDouble(String path);
-
- /**
- * @param path path expression
- * @return the string value at the requested path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a string
- */
- String getString(String path);
-
- /**
- * @param enumClass an enum class
- * @param <T> a generic denoting a specific type of enum
- * @param path path expression
- * @return the {@code Enum} value at the requested path
- * of the requested enum class
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to an Enum
- */
- public <T extends Enum<T>> T getEnum(Class<T> enumClass, String path);
-
- /**
- * @param path path expression
- * @return the {@link ConfigObject} value at the requested path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to an object
- */
- ConfigObject getObject(String path);
-
- /**
- * @param path path expression
- * @return the nested {@code Config} value at the requested path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a Config
- */
- Config getConfig(String path);
-
- /**
- * Gets the value at the path as an unwrapped Java boxed value (
- * {@link java.lang.Boolean Boolean}, {@link java.lang.Integer Integer}, and
- * so on - see {@link ConfigValue#unwrapped()}).
- *
- * @param path path expression
- * @return the unwrapped value at the requested path
- * @throws ConfigException.Missing if value is absent or null
- */
- Object getAnyRef(String path);
-
- /**
- * Gets the value at the given path, unless the value is a
- * null value or missing, in which case it throws just like
- * the other getters. Use {@code get()} on the {@link
- * Config#root()} object (or other object in the tree) if you
- * want an unprocessed value.
- *
- * @param path path expression
- * @return the value at the requested path
- * @throws ConfigException.Missing if value is absent or null
- */
- ConfigValue getValue(String path);
-
- /**
- * Gets a value as a size in bytes (parses special strings like "128M"). If
- * the value is already a number, then it's left alone; if it's a string,
- * it's parsed understanding unit suffixes such as "128K", as documented in
- * the <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
- * spec</a>.
- *
- * @param path path expression
- * @return the value at the requested path, in bytes
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to Long or String
- * @throws ConfigException.BadValue if value cannot be parsed as a size in bytes
- */
- Long getBytes(String path);
-
- /**
- * Gets a value as an amount of memory (parses special strings like "128M"). If
- * the value is already a number, then it's left alone; if it's a string,
- * it's parsed understanding unit suffixes such as "128K", as documented in
- * the <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
- * spec</a>.
- *
- * @param path path expression
- * @return the value at the requested path, in bytes
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to Long or String
- * @throws ConfigException.BadValue if value cannot be parsed as a size in bytes
- * @since 1.3.0
- */
- ConfigMemorySize getMemorySize(String path);
-
- /**
- * Get value as a duration in milliseconds. If the value is already a
- * number, then it's left alone; if it's a string, it's parsed understanding
- * units suffixes like "10m" or "5ns" as documented in the <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
- * spec</a>.
- *
- * @param path path expression
- * @return the duration value at the requested path, in milliseconds
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to Long or String
- * @throws ConfigException.BadValue if value cannot be parsed as a number of milliseconds
- * @deprecated As of release 1.1, replaced by {@link #getDuration(String, TimeUnit)}
- */
- @Deprecated
- Long getMilliseconds(String path);
-
- /**
- * Get value as a duration in nanoseconds. If the value is already a number
- * it's taken as milliseconds and converted to nanoseconds. If it's a
- * string, it's parsed understanding unit suffixes, as for
- * {@link #getDuration(String, TimeUnit)}.
- *
- * @param path path expression
- * @return the duration value at the requested path, in nanoseconds
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to Long or String
- * @throws ConfigException.BadValue if value cannot be parsed as a number of nanoseconds
- * @deprecated As of release 1.1, replaced by {@link #getDuration(String, TimeUnit)}
- */
- @Deprecated
- Long getNanoseconds(String path);
-
- /**
- * Gets a value as a duration in a specified
- * {@link java.util.concurrent.TimeUnit TimeUnit}. If the value is already a
- * number, then it's taken as milliseconds and then converted to the
- * requested TimeUnit; if it's a string, it's parsed understanding units
- * suffixes like "10m" or "5ns" as documented in the <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
- * spec</a>.
- *
- * @param path path expression
- * @param unit convert the return value to this time unit
- * @return the duration value at the requested path, in the given TimeUnit
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to Long or String
- * @throws ConfigException.BadValue if value cannot be parsed as a number of the given TimeUnit
- * @since 1.2.0
- */
- long getDuration(String path, TimeUnit unit);
-
- /**
- * Gets a value as a java.time.Duration. If the value is
- * already a number, then it's taken as milliseconds; if it's
- * a string, it's parsed understanding units suffixes like
- * "10m" or "5ns" as documented in the <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
- * spec</a>. This method never returns null.
- *
- * @param path path expression
- * @return the duration value at the requested path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to Long or String
- * @throws ConfigException.BadValue if value cannot be parsed as a number of the given TimeUnit
- * @since 1.3.0
- */
- Duration getDuration(String path);
-
- /**
- * Gets a value as a java.time.Period. If the value is
- * already a number, then it's taken as days; if it's
- * a string, it's parsed understanding units suffixes like
- * "10d" or "5w" as documented in the <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
- * spec</a>. This method never returns null.
- *
- * @param path path expression
- * @return the period value at the requested path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to Long or String
- * @throws ConfigException.BadValue if value cannot be parsed as a number of the given TimeUnit
- * @since 1.3.0
- */
- Period getPeriod(String path);
-
- /**
- * Gets a value as a java.time.temporal.TemporalAmount.
- * This method will first try get get the value as a java.time.Duration, and if unsuccessful,
- * then as a java.time.Period.
- * This means that values like "5m" will be parsed as 5 minutes rather than 5 months
- *
- * @param path path expression
- * @return the temporal value at the requested path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to Long or String
- * @throws ConfigException.BadValue if value cannot be parsed as a TemporalAmount
- */
- TemporalAmount getTemporal(String path);
-
- /**
- * Gets a list value (with any element type) as a {@link ConfigList}, which
- * implements {@code java.util.List<ConfigValue>}. Throws if the path is
- * unset or null.
- *
- * @param path the path to the list value.
- * @return the {@link ConfigList} at the path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a ConfigList
- */
- ConfigList getList(String path);
-
- /**
- * Gets a list value with boolean elements. Throws if the
- * path is unset or null or not a list or contains values not
- * convertible to boolean.
- *
- * @param path the path to the list value.
- * @return the list at the path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a list of booleans
- */
- List<Boolean> getBooleanList(String path);
-
- /**
- * Gets a list value with number elements. Throws if the
- * path is unset or null or not a list or contains values not
- * convertible to number.
- *
- * @param path the path to the list value.
- * @return the list at the path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a list of numbers
- */
- List<Number> getNumberList(String path);
-
- /**
- * Gets a list value with int elements. Throws if the
- * path is unset or null or not a list or contains values not
- * convertible to int.
- *
- * @param path the path to the list value.
- * @return the list at the path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a list of ints
- */
- List<Integer> getIntList(String path);
-
- /**
- * Gets a list value with long elements. Throws if the
- * path is unset or null or not a list or contains values not
- * convertible to long.
- *
- * @param path the path to the list value.
- * @return the list at the path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a list of longs
- */
- List<Long> getLongList(String path);
-
- /**
- * Gets a list value with double elements. Throws if the
- * path is unset or null or not a list or contains values not
- * convertible to double.
- *
- * @param path the path to the list value.
- * @return the list at the path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a list of doubles
- */
- List<Double> getDoubleList(String path);
-
- /**
- * Gets a list value with string elements. Throws if the
- * path is unset or null or not a list or contains values not
- * convertible to string.
- *
- * @param path the path to the list value.
- * @return the list at the path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a list of strings
- */
- List<String> getStringList(String path);
-
- /**
- * Gets a list value with {@code Enum} elements. Throws if the
- * path is unset or null or not a list or contains values not
- * convertible to {@code Enum}.
- *
- * @param enumClass the enum class
- * @param <T> a generic denoting a specific type of enum
- * @param path the path to the list value.
- * @return the list at the path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a list of {@code Enum}
- */
- <T extends Enum<T>> List<T> getEnumList(Class<T> enumClass, String path);
-
- /**
- * Gets a list value with object elements. Throws if the
- * path is unset or null or not a list or contains values not
- * convertible to <code>ConfigObject</code>.
- *
- * @param path the path to the list value.
- * @return the list at the path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a list of objects
- */
- List<? extends ConfigObject> getObjectList(String path);
-
- /**
- * Gets a list value with <code>Config</code> elements.
- * Throws if the path is unset or null or not a list or
- * contains values not convertible to <code>Config</code>.
- *
- * @param path the path to the list value.
- * @return the list at the path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a list of configs
- */
- List<? extends Config> getConfigList(String path);
-
- /**
- * Gets a list value with any kind of elements. Throws if the
- * path is unset or null or not a list. Each element is
- * "unwrapped" (see {@link ConfigValue#unwrapped()}).
- *
- * @param path the path to the list value.
- * @return the list at the path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a list
- */
- List<? extends Object> getAnyRefList(String path);
-
- /**
- * Gets a list value with elements representing a size in
- * bytes. Throws if the path is unset or null or not a list
- * or contains values not convertible to memory sizes.
- *
- * @param path the path to the list value.
- * @return the list at the path
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a list of memory sizes
- */
- List<Long> getBytesList(String path);
-
- /**
- * Gets a list, converting each value in the list to a memory size, using the
- * same rules as {@link #getMemorySize(String)}.
- *
- * @param path a path expression
- * @return list of memory sizes
- * @throws ConfigException.Missing if value is absent or null
- * @throws ConfigException.WrongType if value is not convertible to a list of memory sizes
- * @since 1.3.0
- */
- List<ConfigMemorySize> getMemorySizeList(String path);
-
- /**
- * @param path the path
- * @return list of millisecond values
- * @deprecated As of release 1.1, replaced by {@link #getDurationList(String, TimeUnit)}
- */
- @Deprecated
- List<Long> getMillisecondsList(String path);
-
- /**
- * @param path the path
- * @return list of nanosecond values
- * @deprecated As of release 1.1, replaced by {@link #getDurationList(String, TimeUnit)}
- */
- @Deprecated
- List<Long> getNanosecondsList(String path);
-
- /**
- * Gets a list, converting each value in the list to a duration, using the
- * same rules as {@link #getDuration(String, TimeUnit)}.
- *
- * @param path a path expression
- * @param unit time units of the returned values
- * @return list of durations, in the requested units
- * @since 1.2.0
- */
- List<Long> getDurationList(String path, TimeUnit unit);
-
- /**
- * Gets a list, converting each value in the list to a duration, using the
- * same rules as {@link #getDuration(String)}.
- *
- * @param path a path expression
- * @return list of durations
- * @since 1.3.0
- */
- List<Duration> getDurationList(String path);
-
- /**
- * Clone the config with only the given path (and its children) retained;
- * all sibling paths are removed.
- * <p>
- * Note that path expressions have a syntax and sometimes require quoting
- * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
- *
- * @param path path to keep
- * @return a copy of the config minus all paths except the one specified
- */
- Config withOnlyPath(String path);
-
- /**
- * Clone the config with the given path removed.
- * <p>
- * Note that path expressions have a syntax and sometimes require quoting
- * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
- *
- * @param path path expression to remove
- * @return a copy of the config minus the specified path
- */
- Config withoutPath(String path);
-
- /**
- * Places the config inside another {@code Config} at the given path.
- * <p>
- * Note that path expressions have a syntax and sometimes require quoting
- * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
- *
- * @param path path expression to store this config at.
- * @return a {@code Config} instance containing this config at the given
- * path.
- */
- Config atPath(String path);
-
- /**
- * Places the config inside a {@code Config} at the given key. See also
- * atPath(). Note that a key is NOT a path expression (see
- * {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
- *
- * @param key key to store this config at.
- * @return a {@code Config} instance containing this config at the given
- * key.
- */
- Config atKey(String key);
-
- /**
- * Returns a {@code Config} based on this one, but with the given path set
- * to the given value. Does not modify this instance (since it's immutable).
- * If the path already has a value, that value is replaced. To remove a
- * value, use withoutPath().
- * <p>
- * Note that path expressions have a syntax and sometimes require quoting
- * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
- *
- * @param path path expression for the value's new location
- * @param value value at the new path
- * @return the new instance with the new map entry
- */
- Config withValue(String path, ConfigValue value);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigBeanFactory.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigBeanFactory.java
deleted file mode 100644
index e0e78f5..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigBeanFactory.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import org.apache.seatunnel.config.impl.ConfigBeanImpl;
-
-/**
- * Factory for automatically creating a Java class from a {@link Config}.
- * See {@link #create(Config, Class)}.
- *
- * @since 1.3.0
- */
-public class ConfigBeanFactory {
-
- /**
- * Creates an instance of a class, initializing its fields from a {@link Config}.
- * <p>
- * Example usage:
- *
- * <pre>
- * Config configSource = ConfigFactory.load().getConfig("foo");
- * FooConfig config = ConfigBeanFactory.create(configSource, FooConfig.class);
- * </pre>
- * <p>
- * The Java class should follow JavaBean conventions. Field types
- * can be any of the types you can normally get from a {@link
- * Config}, including <code>java.time.Duration</code> or {@link
- * ConfigMemorySize}. Fields may also be another JavaBean-style
- * class.
- * <p>
- * Fields are mapped to config by converting the config key to
- * camel case. So the key <code>foo-bar</code> becomes JavaBean
- * setter <code>setFooBar</code>.
- *
- * @param config source of config information
- * @param clazz class to be instantiated
- * @param <T> the type of the class to be instantiated
- * @return an instance of the class populated with data from the config
- * @throws ConfigException.BadBean If something is wrong with the JavaBean
- * @throws ConfigException.ValidationFailed If the config doesn't conform to the bean's implied schema
- * @throws ConfigException Can throw the same exceptions as the getters on <code>Config</code>
- * @since 1.3.0
- */
- public static <T> T create(Config config, Class<T> clazz) {
- return ConfigBeanImpl.createInternal(config, clazz);
- }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigException.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigException.java
deleted file mode 100644
index 402adc0..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigException.java
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import org.apache.seatunnel.config.impl.ConfigImplUtil;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.lang.reflect.Field;
-
-/**
- * All exceptions thrown by the library are subclasses of
- * <code>ConfigException</code>.
- */
-public abstract class ConfigException extends RuntimeException implements Serializable {
- private static final long serialVersionUID = 1L;
-
- private final transient ConfigOrigin origin;
-
- protected ConfigException(ConfigOrigin origin, String message,
- Throwable cause) {
- super(origin.description() + ": " + message, cause);
- this.origin = origin;
- }
-
- protected ConfigException(ConfigOrigin origin, String message) {
- this(origin.description() + ": " + message, null);
- }
-
- protected ConfigException(String message, Throwable cause) {
- super(message, cause);
- this.origin = null;
- }
-
- protected ConfigException(String message) {
- this(message, null);
- }
-
- /**
- * Returns an "origin" (such as a filename and line number) for the
- * exception, or null if none is available. If there's no sensible origin
- * for a given exception, or the kind of exception doesn't meaningfully
- * relate to a particular origin file, this returns null. Never assume this
- * will return non-null, it can always return null.
- *
- * @return origin of the problem, or null if unknown/inapplicable
- */
- public ConfigOrigin origin() {
- return origin;
- }
-
- // we customize serialization because ConfigOrigin isn't
- // serializable and we don't want it to be (don't want to
- // support it)
- private void writeObject(java.io.ObjectOutputStream out) throws IOException {
- out.defaultWriteObject();
- ConfigImplUtil.writeOrigin(out, origin);
- }
-
- private void readObject(java.io.ObjectInputStream in) throws IOException,
- ClassNotFoundException {
- in.defaultReadObject();
- ConfigOrigin origin = ConfigImplUtil.readOrigin(in);
- // circumvent "final"
- Field f;
- try {
- f = ConfigException.class.getDeclaredField("origin");
- } catch (NoSuchFieldException e) {
- throw new IOException("ConfigException has no origin field?", e);
- } catch (SecurityException e) {
- throw new IOException("unable to fill out origin field in ConfigException", e);
- }
- f.setAccessible(true);
- try {
- f.set(this, origin);
- } catch (IllegalArgumentException e) {
- throw new IOException("unable to set origin field", e);
- } catch (IllegalAccessException e) {
- throw new IOException("unable to set origin field", e);
- }
- }
-
- /**
- * Exception indicating that the type of a value does not match the type you
- * requested.
- */
- public static class WrongType extends ConfigException {
- private static final long serialVersionUID = 1L;
-
- public WrongType(ConfigOrigin origin, String path, String expected, String actual,
- Throwable cause) {
- super(origin, path + " has type " + actual + " rather than " + expected, cause);
- }
-
- public WrongType(ConfigOrigin origin, String path, String expected, String actual) {
- this(origin, path, expected, actual, null);
- }
-
- public WrongType(ConfigOrigin origin, String message, Throwable cause) {
- super(origin, message, cause);
- }
-
- public WrongType(ConfigOrigin origin, String message) {
- super(origin, message, null);
- }
- }
-
- /**
- * Exception indicates that the setting was never set to anything, not even
- * null.
- */
- public static class Missing extends ConfigException {
- private static final long serialVersionUID = 1L;
-
- public Missing(String path, Throwable cause) {
- super("No configuration setting found for key '" + path + "'",
- cause);
- }
-
- public Missing(String path) {
- this(path, null);
- }
-
- protected Missing(ConfigOrigin origin, String message, Throwable cause) {
- super(origin, message, cause);
- }
-
- protected Missing(ConfigOrigin origin, String message) {
- this(origin, message, null);
- }
- }
-
- /**
- * Exception indicates that the setting was treated as missing because it
- * was set to null.
- */
- public static class Null extends Missing {
- private static final long serialVersionUID = 1L;
-
- private static String makeMessage(String path, String expected) {
- if (expected != null) {
- return "Configuration key '" + path + "' is set to null but expected " + expected;
- }
- return "Configuration key '" + path + "' is null";
- }
-
- public Null(ConfigOrigin origin, String path, String expected,
- Throwable cause) {
- super(origin, makeMessage(path, expected), cause);
- }
-
- public Null(ConfigOrigin origin, String path, String expected) {
- this(origin, path, expected, null);
- }
- }
-
- /**
- * Exception indicating that a value was messed up, for example you may have
- * asked for a duration and the value can't be sensibly parsed as a
- * duration.
- */
- public static class BadValue extends ConfigException {
- private static final long serialVersionUID = 1L;
-
- public BadValue(ConfigOrigin origin, String path, String message,
- Throwable cause) {
- super(origin, "Invalid value at '" + path + "': " + message, cause);
- }
-
- public BadValue(ConfigOrigin origin, String path, String message) {
- this(origin, path, message, null);
- }
-
- public BadValue(String path, String message, Throwable cause) {
- super("Invalid value at '" + path + "': " + message, cause);
- }
-
- public BadValue(String path, String message) {
- this(path, message, null);
- }
- }
-
- /**
- * Exception indicating that a path expression was invalid. Try putting
- * double quotes around path elements that contain "special" characters.
- */
- public static class BadPath extends ConfigException {
- private static final long serialVersionUID = 1L;
-
- public BadPath(ConfigOrigin origin, String path, String message,
- Throwable cause) {
- super(origin,
- path != null ? ("Invalid path '" + path + "': " + message) : message, cause);
- }
-
- public BadPath(ConfigOrigin origin, String path, String message) {
- this(origin, path, message, null);
- }
-
- public BadPath(String path, String message, Throwable cause) {
- super(path != null ? ("Invalid path '" + path + "': " + message) : message, cause);
- }
-
- public BadPath(String path, String message) {
- this(path, message, null);
- }
-
- public BadPath(ConfigOrigin origin, String message) {
- this(origin, null, message);
- }
- }
-
- /**
- * Exception indicating that there's a bug in something (possibly the
- * library itself) or the runtime environment is broken. This exception
- * should never be handled; instead, something should be fixed to keep the
- * exception from occurring. This exception can be thrown by any method in
- * the library.
- */
- public static class BugOrBroken extends ConfigException {
- private static final long serialVersionUID = 1L;
-
- public BugOrBroken(String message, Throwable cause) {
- super(message, cause);
- }
-
- public BugOrBroken(String message) {
- this(message, null);
- }
- }
-
- /**
- * Exception indicating that there was an IO error.
- */
- public static class IO extends ConfigException {
- private static final long serialVersionUID = 1L;
-
- public IO(ConfigOrigin origin, String message, Throwable cause) {
- super(origin, message, cause);
- }
-
- public IO(ConfigOrigin origin, String message) {
- this(origin, message, null);
- }
- }
-
- /**
- * Exception indicating that there was a parse error.
- */
- public static class Parse extends ConfigException {
- private static final long serialVersionUID = 1L;
-
- public Parse(ConfigOrigin origin, String message, Throwable cause) {
- super(origin, message, cause);
- }
-
- public Parse(ConfigOrigin origin, String message) {
- this(origin, message, null);
- }
- }
-
- /**
- * Exception indicating that a substitution did not resolve to anything.
- * Thrown by {@link Config#resolve}.
- */
- public static class UnresolvedSubstitution extends Parse {
- private static final long serialVersionUID = 1L;
-
- public UnresolvedSubstitution(ConfigOrigin origin, String detail, Throwable cause) {
- super(origin, "Could not resolve substitution to a value: " + detail, cause);
- }
-
- public UnresolvedSubstitution(ConfigOrigin origin, String detail) {
- this(origin, detail, null);
- }
- }
-
- /**
- * Exception indicating that you tried to use a function that requires
- * substitutions to be resolved, but substitutions have not been resolved
- * (that is, {@link Config#resolve} was not called). This is always a bug in
- * either application code or the library; it's wrong to write a handler for
- * this exception because you should be able to fix the code to avoid it by
- * adding calls to {@link Config#resolve}.
- */
- public static class NotResolved extends BugOrBroken {
- private static final long serialVersionUID = 1L;
-
- public NotResolved(String message, Throwable cause) {
- super(message, cause);
- }
-
- public NotResolved(String message) {
- this(message, null);
- }
- }
-
- /**
- * Information about a problem that occurred in {@link Config#checkValid}. A
- * {@link ConfigException.ValidationFailed} exception thrown from
- * <code>checkValid()</code> includes a list of problems encountered.
- */
- public static class ValidationProblem {
-
- private final String path;
- private final ConfigOrigin origin;
- private final String problem;
-
- public ValidationProblem(String path, ConfigOrigin origin, String problem) {
- this.path = path;
- this.origin = origin;
- this.problem = problem;
- }
-
- /**
- * Returns the config setting causing the problem.
- *
- * @return the path of the problem setting
- */
- public String path() {
- return path;
- }
-
- /**
- * Returns where the problem occurred (origin may include info on the
- * file, line number, etc.).
- *
- * @return the origin of the problem setting
- */
- public ConfigOrigin origin() {
- return origin;
- }
-
- /**
- * Returns a description of the problem.
- *
- * @return description of the problem
- */
- public String problem() {
- return problem;
- }
-
- @Override
- public String toString() {
- return "ValidationProblem(" + path + "," + origin + "," + problem + ")";
- }
- }
-
- /**
- * Exception indicating that {@link Config#checkValid} found validity
- * problems. The problems are available via the {@link #problems()} method.
- * The <code>getMessage()</code> of this exception is a potentially very
- * long string listing all the problems found.
- */
- public static class ValidationFailed extends ConfigException {
- private static final long serialVersionUID = 1L;
-
- private final Iterable<ValidationProblem> problems;
-
- public ValidationFailed(Iterable<ValidationProblem> problems) {
- super(makeMessage(problems), null);
- this.problems = problems;
- }
-
- public Iterable<ValidationProblem> problems() {
- return problems;
- }
-
- private static String makeMessage(Iterable<ValidationProblem> problems) {
- StringBuilder sb = new StringBuilder();
- for (ValidationProblem p : problems) {
- sb.append(p.origin().description());
- sb.append(": ");
- sb.append(p.path());
- sb.append(": ");
- sb.append(p.problem());
- sb.append(", ");
- }
- if (sb.length() == 0) {
- throw new BugOrBroken(
- "ValidationFailed must have a non-empty list of problems");
- }
- sb.setLength(sb.length() - 2); // chop comma and space
-
- return sb.toString();
- }
- }
-
- /**
- * Some problem with a JavaBean we are trying to initialize.
- *
- * @since 1.3.0
- */
- public static class BadBean extends BugOrBroken {
- private static final long serialVersionUID = 1L;
-
- public BadBean(String message, Throwable cause) {
- super(message, cause);
- }
-
- public BadBean(String message) {
- this(message, null);
- }
- }
-
- /**
- * Exception that doesn't fall into any other category.
- */
- public static class Generic extends ConfigException {
- private static final long serialVersionUID = 1L;
-
- public Generic(String message, Throwable cause) {
- super(message, cause);
- }
-
- public Generic(String message) {
- this(message, null);
- }
- }
-
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigFactory.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigFactory.java
deleted file mode 100644
index 036b19a..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigFactory.java
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import org.apache.seatunnel.config.impl.ConfigImpl;
-import org.apache.seatunnel.config.impl.Parseable;
-
-import java.io.File;
-import java.io.Reader;
-import java.net.URL;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.Callable;
-
-/**
- * Contains static methods for creating {@link Config} instances.
- *
- * <p>
- * See also {@link ConfigValueFactory} which contains static methods for
- * converting Java values into a {@link ConfigObject}. You can then convert a
- * {@code ConfigObject} into a {@code Config} with {@link ConfigObject#toConfig}.
- *
- * <p>
- * The static methods with "load" in the name do some sort of higher-level
- * operation potentially parsing multiple resources and resolving substitutions,
- * while the ones with "parse" in the name just create a {@link ConfigValue}
- * from a resource and nothing else.
- *
- * <p> You can find an example app and library <a
- * href="https://github.com/lightbend/config/tree/master/examples">on
- * GitHub</a>. Also be sure to read the <a
- * href="package-summary.html#package_description">package
- * overview</a> which describes the big picture as shown in those
- * examples.
- */
-public final class ConfigFactory {
- private static final String STRATEGY_PROPERTY_NAME = "config.strategy";
-
- private ConfigFactory() {
- }
-
- /**
- * Loads an application's configuration from the given classpath resource or
- * classpath resource basename, sandwiches it between default reference
- * config and default overrides, and then resolves it. The classpath
- * resource is "raw" (it should have no "/" prefix, and is not made relative
- * to any package, so it's like {@link ClassLoader#getResource} not
- * {@link Class#getResource}).
- *
- * <p>
- * Resources are loaded from the current thread's
- * {@link Thread#getContextClassLoader()}. In general, a library needs its
- * configuration to come from the class loader used to load that library, so
- * the proper "reference.conf" are present.
- *
- * <p>
- * The loaded object will already be resolved (substitutions have already
- * been processed). As a result, if you add more fallbacks then they won't
- * be seen by substitutions. Substitutions are the "${foo.bar}" syntax. If
- * you want to parse additional files or something then you need to use
- * {@link #load(Config)}.
- *
- * <p>
- * To load a standalone resource (without the default reference and default
- * overrides), use {@link #parseResourcesAnySyntax(String)} rather than this
- * method. To load only the reference config use {@link #defaultReference()}
- * and to load only the overrides use {@link #defaultOverrides()}.
- *
- * @param resourceBasename name (optionally without extension) of a resource on classpath
- * @return configuration for an application relative to context class loader
- */
- public static Config load(String resourceBasename) {
- return load(resourceBasename, ConfigParseOptions.defaults(),
- ConfigResolveOptions.defaults());
- }
-
- /**
- * Like {@link #load(String)} but uses the supplied class loader instead of
- * the current thread's context class loader.
- *
- * <p>
- * To load a standalone resource (without the default reference and default
- * overrides), use {@link #parseResourcesAnySyntax(ClassLoader, String)}
- * rather than this method. To load only the reference config use
- * {@link #defaultReference(ClassLoader)} and to load only the overrides use
- * {@link #defaultOverrides(ClassLoader)}.
- *
- * @param loader class loader to look for resources in
- * @param resourceBasename basename (no .conf/.json/.properties suffix)
- * @return configuration for an application relative to given class loader
- */
- public static Config load(ClassLoader loader, String resourceBasename) {
- return load(resourceBasename, ConfigParseOptions.defaults().setClassLoader(loader),
- ConfigResolveOptions.defaults());
- }
-
- /**
- * Like {@link #load(String)} but allows you to specify parse and resolve
- * options.
- *
- * @param resourceBasename the classpath resource name with optional extension
- * @param parseOptions options to use when parsing the resource
- * @param resolveOptions options to use when resolving the stack
- * @return configuration for an application
- */
- public static Config load(String resourceBasename, ConfigParseOptions parseOptions,
- ConfigResolveOptions resolveOptions) {
- ConfigParseOptions withLoader = ensureClassLoader(parseOptions, "load");
- Config appConfig = ConfigFactory.parseResourcesAnySyntax(resourceBasename, withLoader);
- return load(withLoader.getClassLoader(), appConfig, resolveOptions);
- }
-
- /**
- * Like {@link #load(String, ConfigParseOptions, ConfigResolveOptions)} but
- * has a class loader parameter that overrides any from the
- * {@code ConfigParseOptions}.
- *
- * @param loader class loader in which to find resources (overrides loader in
- * parse options)
- * @param resourceBasename the classpath resource name with optional extension
- * @param parseOptions options to use when parsing the resource (class loader
- * overridden)
- * @param resolveOptions options to use when resolving the stack
- * @return configuration for an application
- */
- public static Config load(ClassLoader loader, String resourceBasename,
- ConfigParseOptions parseOptions, ConfigResolveOptions resolveOptions) {
- return load(resourceBasename, parseOptions.setClassLoader(loader), resolveOptions);
- }
-
- private static ClassLoader checkedContextClassLoader(String methodName) {
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- if (loader == null) {
- throw new ConfigException.BugOrBroken("Context class loader is not set for the current thread; "
- + "if Thread.currentThread().getContextClassLoader() returns null, you must pass a ClassLoader "
- + "explicitly to ConfigFactory."
- + methodName);
- }
- return loader;
- }
-
- private static ConfigParseOptions ensureClassLoader(ConfigParseOptions options, String methodName) {
- if (options.getClassLoader() == null) {
- return options.setClassLoader(checkedContextClassLoader(methodName));
- }
- return options;
- }
-
- /**
- * Assembles a standard configuration using a custom <code>Config</code>
- * object rather than loading "application.conf". The <code>Config</code>
- * object will be sandwiched between the default reference config and
- * default overrides and then resolved.
- *
- * @param config the application's portion of the configuration
- * @return resolved configuration with overrides and fallbacks added
- */
- public static Config load(Config config) {
- return load(checkedContextClassLoader("load"), config);
- }
-
- /**
- * Like {@link #load(Config)} but allows you to specify
- * the class loader for looking up resources.
- *
- * @param loader the class loader to use to find resources
- * @param config the application's portion of the configuration
- * @return resolved configuration with overrides and fallbacks added
- */
- public static Config load(ClassLoader loader, Config config) {
- return load(loader, config, ConfigResolveOptions.defaults());
- }
-
- /**
- * Like {@link #load(Config)} but allows you to specify
- * {@link ConfigResolveOptions}.
- *
- * @param config the application's portion of the configuration
- * @param resolveOptions options for resolving the assembled config stack
- * @return resolved configuration with overrides and fallbacks added
- */
- public static Config load(Config config, ConfigResolveOptions resolveOptions) {
- return load(checkedContextClassLoader("load"), config, resolveOptions);
- }
-
- /**
- * Like {@link #load(Config, ConfigResolveOptions)} but allows you to specify
- * a class loader other than the context class loader.
- *
- * @param loader class loader to use when looking up override and reference
- * configs
- * @param config the application's portion of the configuration
- * @param resolveOptions options for resolving the assembled config stack
- * @return resolved configuration with overrides and fallbacks added
- */
- public static Config load(ClassLoader loader, Config config, ConfigResolveOptions resolveOptions) {
- return defaultOverrides(loader).withFallback(config).withFallback(defaultReference(loader))
- .resolve(resolveOptions);
- }
-
-
- /**
- * Loads a default configuration, equivalent to {@link #load(Config)
- * load(defaultApplication())} in most cases. This configuration should be used by
- * libraries and frameworks unless an application provides a different one.
- * <p>
- * This method may return a cached singleton so will not see changes to
- * system properties or config files. (Use {@link #invalidateCaches()} to
- * force it to reload.)
- *
- * @return configuration for an application
- */
- public static Config load() {
- ClassLoader loader = checkedContextClassLoader("load");
- return load(loader);
- }
-
- /**
- * Like {@link #load()} but allows specifying parse options.
- *
- * @param parseOptions Options for parsing resources
- * @return configuration for an application
- */
- public static Config load(ConfigParseOptions parseOptions) {
- return load(parseOptions, ConfigResolveOptions.defaults());
- }
-
- /**
- * Like {@link #load()} but allows specifying a class loader other than the
- * thread's current context class loader.
- *
- * @param loader class loader for finding resources
- * @return configuration for an application
- */
- public static Config load(final ClassLoader loader) {
- final ConfigParseOptions withLoader = ConfigParseOptions.defaults().setClassLoader(loader);
- return ConfigImpl.computeCachedConfig(loader, "load", new Callable<Config>() {
- @Override
- public Config call() {
- return load(loader, defaultApplication(withLoader));
- }
- });
- }
-
- /**
- * Like {@link #load()} but allows specifying a class loader other than the
- * thread's current context class loader and also specify parse options.
- *
- * @param loader class loader for finding resources (overrides any loader in parseOptions)
- * @param parseOptions Options for parsing resources
- * @return configuration for an application
- */
- public static Config load(ClassLoader loader, ConfigParseOptions parseOptions) {
- return load(parseOptions.setClassLoader(loader));
- }
-
- /**
- * Like {@link #load()} but allows specifying a class loader other than the
- * thread's current context class loader and also specify resolve options.
- *
- * @param loader class loader for finding resources
- * @param resolveOptions options for resolving the assembled config stack
- * @return configuration for an application
- */
- public static Config load(ClassLoader loader, ConfigResolveOptions resolveOptions) {
- return load(loader, ConfigParseOptions.defaults(), resolveOptions);
- }
-
-
- /**
- * Like {@link #load()} but allows specifying a class loader other than the
- * thread's current context class loader, parse options, and resolve options.
- *
- * @param loader class loader for finding resources (overrides any loader in parseOptions)
- * @param parseOptions Options for parsing resources
- * @param resolveOptions options for resolving the assembled config stack
- * @return configuration for an application
- */
- public static Config load(ClassLoader loader, ConfigParseOptions parseOptions, ConfigResolveOptions resolveOptions) {
- final ConfigParseOptions withLoader = ensureClassLoader(parseOptions, "load");
- return load(loader, defaultApplication(withLoader), resolveOptions);
- }
-
- /**
- * Like {@link #load()} but allows specifying parse options and resolve
- * options.
- *
- * @param parseOptions Options for parsing resources
- * @param resolveOptions options for resolving the assembled config stack
- * @return configuration for an application
- * @since 1.3.0
- */
- public static Config load(ConfigParseOptions parseOptions, final ConfigResolveOptions resolveOptions) {
- final ConfigParseOptions withLoader = ensureClassLoader(parseOptions, "load");
- return load(defaultApplication(withLoader), resolveOptions);
- }
-
- /**
- * Obtains the default reference configuration, which is currently created
- * by merging all resources "reference.conf" found on the classpath and
- * overriding the result with system properties. The returned reference
- * configuration will already have substitutions resolved.
- *
- * <p>
- * Libraries and frameworks should ship with a "reference.conf" in their
- * jar.
- *
- * <p>
- * The reference config must be looked up in the class loader that contains
- * the libraries that you want to use with this config, so the
- * "reference.conf" for each library can be found. Use
- * {@link #defaultReference(ClassLoader)} if the context class loader is not
- * suitable.
- *
- * <p>
- * The {@link #load()} methods merge this configuration for you
- * automatically.
- *
- * <p>
- * Future versions may look for reference configuration in more places. It
- * is not guaranteed that this method <em>only</em> looks at
- * "reference.conf".
- *
- * @return the default reference config for context class loader
- */
- public static Config defaultReference() {
- return defaultReference(checkedContextClassLoader("defaultReference"));
- }
-
- /**
- * Like {@link #defaultReference()} but allows you to specify a class loader
- * to use rather than the current context class loader.
- *
- * @param loader class loader to look for resources in
- * @return the default reference config for this class loader
- */
- public static Config defaultReference(ClassLoader loader) {
- return ConfigImpl.defaultReference(loader);
- }
-
- /**
- * Obtains the default override configuration, which currently consists of
- * system properties. The returned override configuration will already have
- * substitutions resolved.
- *
- * <p>
- * The {@link #load()} methods merge this configuration for you
- * automatically.
- *
- * <p>
- * Future versions may get overrides in more places. It is not guaranteed
- * that this method <em>only</em> uses system properties.
- *
- * @return the default override configuration
- */
- public static Config defaultOverrides() {
- return systemProperties();
- }
-
- /**
- * Like {@link #defaultOverrides()} but allows you to specify a class loader
- * to use rather than the current context class loader.
- *
- * @param loader class loader to look for resources in
- * @return the default override configuration
- */
- public static Config defaultOverrides(ClassLoader loader) {
- return systemProperties();
- }
-
- /**
- * Obtains the default application-specific configuration,
- * which defaults to parsing <code>application.conf</code>,
- * <code>application.json</code>, and
- * <code>application.properties</code> on the classpath, but
- * can also be rerouted using the <code>config.file</code>,
- * <code>config.resource</code>, and <code>config.url</code>
- * system properties.
- *
- * <p> The no-arguments {@link #load()} method automatically
- * stacks the {@link #defaultReference()}, {@link
- * #defaultApplication()}, and {@link #defaultOverrides()}
- * configs. You would use <code>defaultApplication()</code>
- * directly only if you're somehow customizing behavior by
- * reimplementing <code>load()</code>.
- *
- * <p>The configuration returned by
- * <code>defaultApplication()</code> will not be resolved
- * already, in contrast to <code>defaultReference()</code> and
- * <code>defaultOverrides()</code>. This is because
- * application.conf would normally be resolved <em>after</em>
- * merging with the reference and override configs.
- *
- * <p>
- * If the system properties <code>config.resource</code>,
- * <code>config.file</code>, or <code>config.url</code> are set, then the
- * classpath resource, file, or URL specified in those properties will be
- * used rather than the default
- * <code>application.{conf,json,properties}</code> classpath resources.
- * These system properties should not be set in code (after all, you can
- * just parse whatever you want manually and then use {@link #load(Config)}
- * if you don't want to use <code>application.conf</code>). The properties
- * are intended for use by the person or script launching the application.
- * For example someone might have a <code>production.conf</code> that
- * include <code>application.conf</code> but then change a couple of values.
- * When launching the app they could specify
- * <code>-Dconfig.resource=production.conf</code> to get production mode.
- *
- * <p>
- * If no system properties are set to change the location of the default
- * configuration, <code>defaultApplication()</code> is equivalent to
- * <code>ConfigFactory.parseResources("application")</code>.
- *
- * @return the default application.conf or system-property-configured configuration
- * @since 1.3.0
- */
- public static Config defaultApplication() {
- return defaultApplication(ConfigParseOptions.defaults());
- }
-
- /**
- * Like {@link #defaultApplication()} but allows you to specify a class loader
- * to use rather than the current context class loader.
- *
- * @param loader class loader to look for resources in
- * @return the default application configuration
- * @since 1.3.0
- */
- public static Config defaultApplication(ClassLoader loader) {
- return defaultApplication(ConfigParseOptions.defaults().setClassLoader(loader));
- }
-
- /**
- * Like {@link #defaultApplication()} but allows you to specify parse options.
- *
- * @param options the options
- * @return the default application configuration
- * @since 1.3.0
- */
- public static Config defaultApplication(ConfigParseOptions options) {
- return getConfigLoadingStrategy().parseApplicationConfig(ensureClassLoader(options, "defaultApplication"));
- }
-
- /**
- * Reloads any cached configs, picking up changes to system properties for
- * example. Because a {@link Config} is immutable, anyone with a reference
- * to the old configs will still have the same outdated objects. However,
- * new calls to {@link #load()} or {@link #defaultOverrides()} or
- * {@link #defaultReference} may return a new object.
- * <p>
- * This method is primarily intended for use in unit tests, for example,
- * that may want to update a system property then confirm that it's used
- * correctly. In many cases, use of this method may indicate there's a
- * better way to set up your code.
- * <p>
- * Caches may be reloaded immediately or lazily; once you call this method,
- * the reload can occur at any time, even during the invalidation process.
- * So FIRST make the changes you'd like the caches to notice, then SECOND
- * call this method to invalidate caches. Don't expect that invalidating,
- * making changes, then calling {@link #load()}, will work. Make changes
- * before you invalidate.
- */
- public static void invalidateCaches() {
- // We rely on this having the side effect that it drops
- // all caches
- ConfigImpl.reloadSystemPropertiesConfig();
- ConfigImpl.reloadEnvVariablesConfig();
- }
-
- /**
- * Gets an empty configuration. See also {@link #empty(String)} to create an
- * empty configuration with a description, which may improve user-visible
- * error messages.
- *
- * @return an empty configuration
- */
- public static Config empty() {
- return empty(null);
- }
-
- /**
- * Gets an empty configuration with a description to be used to create a
- * {@link ConfigOrigin} for this <code>Config</code>. The description should
- * be very short and say what the configuration is, like "default settings"
- * or "foo settings" or something. (Presumably you will merge some actual
- * settings into this empty config using {@link Config#withFallback}, making
- * the description more useful.)
- *
- * @param originDescription description of the config
- * @return an empty configuration
- */
- public static Config empty(String originDescription) {
- return ConfigImpl.emptyConfig(originDescription);
- }
-
- /**
- * Gets a <code>Config</code> containing the system properties from
- * {@link java.lang.System#getProperties()}, parsed and converted as with
- * {@link #parseProperties}.
- * <p>
- * This method can return a global immutable singleton, so it's preferred
- * over parsing system properties yourself.
- * <p>
- * {@link #load} will include the system properties as overrides already, as
- * will {@link #defaultReference} and {@link #defaultOverrides}.
- *
- * <p>
- * Because this returns a singleton, it will not notice changes to system
- * properties made after the first time this method is called. Use
- * {@link #invalidateCaches()} to force the singleton to reload if you
- * modify system properties.
- *
- * @return system properties parsed into a <code>Config</code>
- */
- public static Config systemProperties() {
- return ConfigImpl.systemPropertiesAsConfig();
- }
-
- /**
- * Gets a <code>Config</code> containing the system's environment variables.
- * This method can return a global immutable singleton.
- *
- * <p>
- * Environment variables are used as fallbacks when resolving substitutions
- * whether or not this object is included in the config being resolved, so
- * you probably don't need to use this method for most purposes. It can be a
- * nicer API for accessing environment variables than raw
- * {@link java.lang.System#getenv(String)} though, since you can use methods
- * such as {@link Config#getInt}.
- *
- * @return system environment variables parsed into a <code>Config</code>
- */
- public static Config systemEnvironment() {
- return ConfigImpl.envVariablesAsConfig();
- }
-
- /**
- * Converts a Java {@link java.util.Properties} object to a
- * {@link ConfigObject} using the rules documented in the <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">HOCON
- * spec</a>. The keys in the <code>Properties</code> object are split on the
- * period character '.' and treated as paths. The values will all end up as
- * string values. If you have both "a=foo" and "a.b=bar" in your properties
- * file, so "a" is both the object containing "b" and the string "foo", then
- * the string value is dropped.
- *
- * <p>
- * If you want to have <code>System.getProperties()</code> as a
- * ConfigObject, it's better to use the {@link #systemProperties()} method
- * which returns a cached global singleton.
- *
- * @param properties a Java Properties object
- * @param options the parse options
- * @return the parsed configuration
- */
- public static Config parseProperties(Properties properties,
- ConfigParseOptions options) {
- return Parseable.newProperties(properties, options).parse().toConfig();
- }
-
- /**
- * Like {@link #parseProperties(Properties, ConfigParseOptions)} but uses default
- * parse options.
- *
- * @param properties a Java Properties object
- * @return the parsed configuration
- */
- public static Config parseProperties(Properties properties) {
- return parseProperties(properties, ConfigParseOptions.defaults());
- }
-
- /**
- * Parses a Reader into a Config instance. Does not call
- * {@link Config#resolve} or merge the parsed stream with any
- * other configuration; this method parses a single stream and
- * does nothing else. It does process "include" statements in
- * the parsed stream, and may end up doing other IO due to those
- * statements.
- *
- * @param reader the reader to parse
- * @param options parse options to control how the reader is interpreted
- * @return the parsed configuration
- * @throws ConfigException on IO or parse errors
- */
- public static Config parseReader(Reader reader, ConfigParseOptions options) {
- return Parseable.newReader(reader, options).parse().toConfig();
- }
-
- /**
- * Parses a reader into a Config instance as with
- * {@link #parseReader(Reader, ConfigParseOptions)} but always uses the
- * default parse options.
- *
- * @param reader the reader to parse
- * @return the parsed configuration
- * @throws ConfigException on IO or parse errors
- */
- public static Config parseReader(Reader reader) {
- return parseReader(reader, ConfigParseOptions.defaults());
- }
-
- /**
- * Parses a URL into a Config instance. Does not call
- * {@link Config#resolve} or merge the parsed stream with any
- * other configuration; this method parses a single stream and
- * does nothing else. It does process "include" statements in
- * the parsed stream, and may end up doing other IO due to those
- * statements.
- *
- * @param url the url to parse
- * @param options parse options to control how the url is interpreted
- * @return the parsed configuration
- * @throws ConfigException on IO or parse errors
- */
- public static Config parseURL(URL url, ConfigParseOptions options) {
- return Parseable.newURL(url, options).parse().toConfig();
- }
-
- /**
- * Parses a url into a Config instance as with
- * {@link #parseURL(URL, ConfigParseOptions)} but always uses the
- * default parse options.
- *
- * @param url the url to parse
- * @return the parsed configuration
- * @throws ConfigException on IO or parse errors
- */
- public static Config parseURL(URL url) {
- return parseURL(url, ConfigParseOptions.defaults());
- }
-
- /**
- * Parses a file into a Config instance. Does not call
- * {@link Config#resolve} or merge the file with any other
- * configuration; this method parses a single file and does
- * nothing else. It does process "include" statements in the
- * parsed file, and may end up doing other IO due to those
- * statements.
- *
- * @param file the file to parse
- * @param options parse options to control how the file is interpreted
- * @return the parsed configuration
- * @throws ConfigException on IO or parse errors
- */
- public static Config parseFile(File file, ConfigParseOptions options) {
- return Parseable.newFile(file, options).parse().toConfig();
- }
-
- /**
- * Parses a file into a Config instance as with
- * {@link #parseFile(File, ConfigParseOptions)} but always uses the
- * default parse options.
- *
- * @param file the file to parse
- * @return the parsed configuration
- * @throws ConfigException on IO or parse errors
- */
- public static Config parseFile(File file) {
- return parseFile(file, ConfigParseOptions.defaults());
- }
-
- /**
- * Parses a file with a flexible extension. If the <code>fileBasename</code>
- * already ends in a known extension, this method parses it according to
- * that extension (the file's syntax must match its extension). If the
- * <code>fileBasename</code> does not end in an extension, it parses files
- * with all known extensions and merges whatever is found.
- *
- * <p>
- * In the current implementation, the extension ".conf" forces
- * {@link ConfigSyntax#CONF}, ".json" forces {@link ConfigSyntax#JSON}, and
- * ".properties" forces {@link ConfigSyntax#PROPERTIES}. When merging files,
- * ".conf" falls back to ".json" falls back to ".properties".
- *
- * <p>
- * Future versions of the implementation may add additional syntaxes or
- * additional extensions. However, the ordering (fallback priority) of the
- * three current extensions will remain the same.
- *
- * <p>
- * If <code>options</code> forces a specific syntax, this method only parses
- * files with an extension matching that syntax.
- *
- * <p>
- * If {@link ConfigParseOptions#getAllowMissing options.getAllowMissing()}
- * is true, then no files have to exist; if false, then at least one file
- * has to exist.
- *
- * @param fileBasename a filename with or without extension
- * @param options parse options
- * @return the parsed configuration
- */
- public static Config parseFileAnySyntax(File fileBasename,
- ConfigParseOptions options) {
- return ConfigImpl.parseFileAnySyntax(fileBasename, options).toConfig();
- }
-
- /**
- * Like {@link #parseFileAnySyntax(File, ConfigParseOptions)} but always uses
- * default parse options.
- *
- * @param fileBasename a filename with or without extension
- * @return the parsed configuration
- */
- public static Config parseFileAnySyntax(File fileBasename) {
- return parseFileAnySyntax(fileBasename, ConfigParseOptions.defaults());
- }
-
- /**
- * Parses all resources on the classpath with the given name and merges them
- * into a single <code>Config</code>.
- *
- * <p>
- * If the resource name does not begin with a "/", it will have the supplied
- * class's package added to it, in the same way as
- * {@link java.lang.Class#getResource}.
- *
- * <p>
- * Duplicate resources with the same name are merged such that ones returned
- * earlier from {@link ClassLoader#getResources} fall back to (have higher
- * priority than) the ones returned later. This implies that resources
- * earlier in the classpath override those later in the classpath when they
- * configure the same setting. However, in practice real applications may
- * not be consistent about classpath ordering, so be careful. It may be best
- * to avoid assuming too much.
- *
- * @param klass <code>klass.getClassLoader()</code> will be used to load
- * resources, and non-absolute resource names will have this
- * class's package added
- * @param resource resource to look up, relative to <code>klass</code>'s package
- * or absolute starting with a "/"
- * @param options parse options
- * @return the parsed configuration
- */
- public static Config parseResources(Class<?> klass, String resource,
- ConfigParseOptions options) {
- return Parseable.newResources(klass, resource, options).parse()
- .toConfig();
- }
-
- /**
- * Like {@link #parseResources(Class, String, ConfigParseOptions)} but always uses
- * default parse options.
- *
- * @param klass <code>klass.getClassLoader()</code> will be used to load
- * resources, and non-absolute resource names will have this
- * class's package added
- * @param resource resource to look up, relative to <code>klass</code>'s package
- * or absolute starting with a "/"
- * @return the parsed configuration
- */
- public static Config parseResources(Class<?> klass, String resource) {
- return parseResources(klass, resource, ConfigParseOptions.defaults());
- }
-
- /**
- * Parses classpath resources with a flexible extension. In general, this
- * method has the same behavior as
- * {@link #parseFileAnySyntax(File, ConfigParseOptions)} but for classpath
- * resources instead, as in {@link #parseResources}.
- *
- * <p>
- * There is a thorny problem with this method, which is that
- * {@link java.lang.ClassLoader#getResources} must be called separately for
- * each possible extension. The implementation ends up with separate lists
- * of resources called "basename.conf" and "basename.json" for example. As a
- * result, the ideal ordering between two files with different extensions is
- * unknown; there is no way to figure out how to merge the two lists in
- * classpath order. To keep it simple, the lists are simply concatenated,
- * with the same syntax priorities as
- * {@link #parseFileAnySyntax(File, ConfigParseOptions) parseFileAnySyntax()}
- * - all ".conf" resources are ahead of all ".json" resources which are
- * ahead of all ".properties" resources.
- *
- * @param klass class which determines the <code>ClassLoader</code> and the
- * package for relative resource names
- * @param resourceBasename a resource name as in {@link java.lang.Class#getResource},
- * with or without extension
- * @param options parse options (class loader is ignored in favor of the one
- * from klass)
- * @return the parsed configuration
- */
- public static Config parseResourcesAnySyntax(Class<?> klass, String resourceBasename,
- ConfigParseOptions options) {
- return ConfigImpl.parseResourcesAnySyntax(klass, resourceBasename,
- options).toConfig();
- }
-
- /**
- * Like {@link #parseResourcesAnySyntax(Class, String, ConfigParseOptions)}
- * but always uses default parse options.
- *
- * @param klass <code>klass.getClassLoader()</code> will be used to load
- * resources, and non-absolute resource names will have this
- * class's package added
- * @param resourceBasename a resource name as in {@link java.lang.Class#getResource},
- * with or without extension
- * @return the parsed configuration
- */
- public static Config parseResourcesAnySyntax(Class<?> klass, String resourceBasename) {
- return parseResourcesAnySyntax(klass, resourceBasename, ConfigParseOptions.defaults());
- }
-
- /**
- * Parses all resources on the classpath with the given name and merges them
- * into a single <code>Config</code>.
- *
- * <p>
- * This works like {@link java.lang.ClassLoader#getResource}, not like
- * {@link java.lang.Class#getResource}, so the name never begins with a
- * slash.
- *
- * <p>
- * See {@link #parseResources(Class, String, ConfigParseOptions)} for full
- * details.
- *
- * @param loader will be used to load resources by setting this loader on the
- * provided options
- * @param resource resource to look up
- * @param options parse options (class loader is ignored)
- * @return the parsed configuration
- */
- public static Config parseResources(ClassLoader loader, String resource,
- ConfigParseOptions options) {
- return parseResources(resource, options.setClassLoader(loader));
- }
-
- /**
- * Like {@link #parseResources(ClassLoader, String, ConfigParseOptions)} but always uses
- * default parse options.
- *
- * @param loader will be used to load resources
- * @param resource resource to look up in the loader
- * @return the parsed configuration
- */
- public static Config parseResources(ClassLoader loader, String resource) {
- return parseResources(loader, resource, ConfigParseOptions.defaults());
- }
-
- /**
- * Parses classpath resources with a flexible extension. In general, this
- * method has the same behavior as
- * {@link #parseFileAnySyntax(File, ConfigParseOptions)} but for classpath
- * resources instead, as in
- * {@link #parseResources(ClassLoader, String, ConfigParseOptions)}.
- *
- * <p>
- * {@link #parseResourcesAnySyntax(Class, String, ConfigParseOptions)} differs
- * in the syntax for the resource name, but otherwise see
- * {@link #parseResourcesAnySyntax(Class, String, ConfigParseOptions)} for
- * some details and caveats on this method.
- *
- * @param loader class loader to look up resources in, will be set on options
- * @param resourceBasename a resource name as in
- * {@link java.lang.ClassLoader#getResource}, with or without
- * extension
- * @param options parse options (class loader ignored)
- * @return the parsed configuration
- */
- public static Config parseResourcesAnySyntax(ClassLoader loader, String resourceBasename,
- ConfigParseOptions options) {
- return ConfigImpl.parseResourcesAnySyntax(resourceBasename, options.setClassLoader(loader))
- .toConfig();
- }
-
- /**
- * Like {@link #parseResourcesAnySyntax(ClassLoader, String, ConfigParseOptions)} but always uses
- * default parse options.
- *
- * @param loader will be used to load resources
- * @param resourceBasename a resource name as in
- * {@link java.lang.ClassLoader#getResource}, with or without
- * extension
- * @return the parsed configuration
- */
- public static Config parseResourcesAnySyntax(ClassLoader loader, String resourceBasename) {
- return parseResourcesAnySyntax(loader, resourceBasename, ConfigParseOptions.defaults());
- }
-
- /**
- * Like {@link #parseResources(ClassLoader, String, ConfigParseOptions)} but
- * uses thread's current context class loader if none is set in the
- * ConfigParseOptions.
- *
- * @param resource the resource name
- * @param options parse options
- * @return the parsed configuration
- */
- public static Config parseResources(String resource, ConfigParseOptions options) {
- ConfigParseOptions withLoader = ensureClassLoader(options, "parseResources");
- return Parseable.newResources(resource, withLoader).parse().toConfig();
- }
-
- /**
- * Like {@link #parseResources(ClassLoader, String)} but uses thread's
- * current context class loader.
- *
- * @param resource the resource name
- * @return the parsed configuration
- */
- public static Config parseResources(String resource) {
- return parseResources(resource, ConfigParseOptions.defaults());
- }
-
- /**
- * Like
- * {@link #parseResourcesAnySyntax(ClassLoader, String, ConfigParseOptions)}
- * but uses thread's current context class loader.
- *
- * @param resourceBasename the resource basename (no file type suffix)
- * @param options parse options
- * @return the parsed configuration
- */
- public static Config parseResourcesAnySyntax(String resourceBasename, ConfigParseOptions options) {
- return ConfigImpl.parseResourcesAnySyntax(resourceBasename, options).toConfig();
- }
-
- /**
- * Like {@link #parseResourcesAnySyntax(ClassLoader, String)} but uses
- * thread's current context class loader.
- *
- * @param resourceBasename the resource basename (no file type suffix)
- * @return the parsed configuration
- */
- public static Config parseResourcesAnySyntax(String resourceBasename) {
- return parseResourcesAnySyntax(resourceBasename, ConfigParseOptions.defaults());
- }
-
- /**
- * Parses a string (which should be valid HOCON or JSON by default, or
- * the syntax specified in the options otherwise).
- *
- * @param s string to parse
- * @param options parse options
- * @return the parsed configuration
- */
- public static Config parseString(String s, ConfigParseOptions options) {
- return Parseable.newString(s, options).parse().toConfig();
- }
-
- /**
- * Parses a string (which should be valid HOCON or JSON).
- *
- * @param s string to parse
- * @return the parsed configuration
- */
- public static Config parseString(String s) {
- return parseString(s, ConfigParseOptions.defaults());
- }
-
- /**
- * Creates a {@code Config} based on a {@link java.util.Map} from paths to
- * plain Java values. Similar to
- * {@link ConfigValueFactory#fromMap(Map, String)}, except the keys in the
- * map are path expressions, rather than keys; and correspondingly it
- * returns a {@code Config} instead of a {@code ConfigObject}. This is more
- * convenient if you are writing literal maps in code, and less convenient
- * if you are getting your maps from some data source such as a parser.
- *
- * <p>
- * An exception will be thrown (and it is a bug in the caller of the method)
- * if a path is both an object and a value, for example if you had both
- * "a=foo" and "a.b=bar", then "a" is both the string "foo" and the parent
- * object of "b". The caller of this method should ensure that doesn't
- * happen.
- *
- * @param values map from paths to plain Java objects
- * @param originDescription description of what this map represents, like a filename, or
- * "default settings" (origin description is used in error
- * messages)
- * @return the map converted to a {@code Config}
- */
- public static Config parseMap(Map<String, ? extends Object> values,
- String originDescription) {
- return ConfigImpl.fromPathMap(values, originDescription).toConfig();
- }
-
- /**
- * See the other overload of {@link #parseMap(Map, String)} for details,
- * this one just uses a default origin description.
- *
- * @param values map from paths to plain Java values
- * @return the map converted to a {@code Config}
- */
- public static Config parseMap(Map<String, ? extends Object> values) {
- return parseMap(values, null);
- }
-
- private static ConfigLoadingStrategy getConfigLoadingStrategy() {
- String className = System.getProperties().getProperty(STRATEGY_PROPERTY_NAME);
-
- if (className != null) {
- try {
- return ConfigLoadingStrategy.class.cast(Class.forName(className).newInstance());
- } catch (Throwable e) {
- throw new ConfigException.BugOrBroken("Failed to load strategy: " + className, e);
- }
- }
- return new DefaultConfigLoadingStrategy();
- }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncludeContext.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncludeContext.java
deleted file mode 100644
index 892b018..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncludeContext.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-/**
- * Context provided to a {@link ConfigIncluder}; this interface is only useful
- * inside a {@code ConfigIncluder} implementation, and is not intended for apps
- * to implement.
- *
- * <p>
- * <em>Do not implement this interface</em>; it should only be implemented by
- * the config library. Arbitrary implementations will not work because the
- * library internals assume a specific concrete implementation. Also, this
- * interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigIncludeContext {
- /**
- * Tries to find a name relative to whatever is doing the including, for
- * example in the same directory as the file doing the including. Returns
- * null if it can't meaningfully create a relative name. The returned
- * parseable may not exist; this function is not required to do any IO, just
- * compute what the name would be.
- * <p>
- * The passed-in filename has to be a complete name (with extension), not
- * just a basename. (Include statements in config files are allowed to give
- * just a basename.)
- *
- * @param filename the name to make relative to the resource doing the including
- * @return parseable item relative to the resource doing the including, or
- * null
- */
- ConfigParseable relativeTo(String filename);
-
- /**
- * Parse options to use (if you use another method to get a
- * {@link ConfigParseable} then use {@link ConfigParseable#options()}
- * instead though).
- *
- * @return the parse options
- */
- ConfigParseOptions parseOptions();
-
-
- /**
- * Copy this {@link ConfigIncludeContext} giving it a new value for its parseOptions.
- *
- * @param options new parse options to use
- * @return the updated copy of this context
- */
- ConfigIncludeContext setParseOptions(ConfigParseOptions options);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluder.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluder.java
deleted file mode 100644
index cac9c28..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluder.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-/**
- * Implement this interface and provide an instance to
- * {@link ConfigParseOptions#setIncluder ConfigParseOptions.setIncluder()} to
- * customize handling of {@code include} statements in config files. You may
- * also want to implement {@link ConfigIncluderClasspath},
- * {@link ConfigIncluderFile}, and {@link ConfigIncluderURL}, or not.
- */
-public interface ConfigIncluder {
- /**
- * Returns a new includer that falls back to the given includer. This is how
- * you can obtain the default includer; it will be provided as a fallback.
- * It's up to your includer to chain to it if you want to. You might want to
- * merge any files found by the fallback includer with any objects you load
- * yourself.
- * <p>
- * It's important to handle the case where you already have the fallback
- * with a "return this", i.e. this method should not create a new object if
- * the fallback is the same one you already have. The same fallback may be
- * added repeatedly.
- *
- * @param fallback the previous includer for chaining
- * @return a new includer
- */
- ConfigIncluder withFallback(ConfigIncluder fallback);
-
- /**
- * Parses another item to be included. The returned object typically would
- * not have substitutions resolved. You can throw a ConfigException here to
- * abort parsing, or return an empty object, but may not return null.
- * <p>
- * This method is used for a "heuristic" include statement that does not
- * specify file, URL, or classpath resource. If the include statement does
- * specify, then the same class implementing {@link ConfigIncluder} must
- * also implement {@link ConfigIncluderClasspath},
- * {@link ConfigIncluderFile}, or {@link ConfigIncluderURL} as needed, or a
- * default includer will be used.
- *
- * @param context some info about the include context
- * @param what the include statement's argument
- * @return a non-null ConfigObject
- */
- ConfigObject include(ConfigIncludeContext context, String what);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderClasspath.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderClasspath.java
deleted file mode 100644
index d9876a3..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderClasspath.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-/**
- * Implement this <em>in addition to</em> {@link ConfigIncluder} if you want to
- * support inclusion of files with the {@code include classpath("resource")}
- * syntax. If you do not implement this but do implement {@link ConfigIncluder},
- * attempts to load classpath resources will use the default includer.
- */
-public interface ConfigIncluderClasspath {
- /**
- * Parses another item to be included. The returned object typically would
- * not have substitutions resolved. You can throw a ConfigException here to
- * abort parsing, or return an empty object, but may not return null.
- *
- * @param context some info about the include context
- * @param what the include statement's argument
- * @return a non-null ConfigObject
- */
- ConfigObject includeResources(ConfigIncludeContext context, String what);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderFile.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderFile.java
deleted file mode 100644
index 86fc2e3..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderFile.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import java.io.File;
-
-/**
- * Implement this <em>in addition to</em> {@link ConfigIncluder} if you want to
- * support inclusion of files with the {@code include file("filename")} syntax.
- * If you do not implement this but do implement {@link ConfigIncluder},
- * attempts to load files will use the default includer.
- */
-public interface ConfigIncluderFile {
- /**
- * Parses another item to be included. The returned object typically would
- * not have substitutions resolved. You can throw a ConfigException here to
- * abort parsing, or return an empty object, but may not return null.
- *
- * @param context some info about the include context
- * @param what the include statement's argument
- * @return a non-null ConfigObject
- */
- ConfigObject includeFile(ConfigIncludeContext context, File what);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderURL.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderURL.java
deleted file mode 100644
index fe27ebb..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderURL.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import java.net.URL;
-
-/**
- * Implement this <em>in addition to</em> {@link ConfigIncluder} if you want to
- * support inclusion of files with the {@code include url("http://example.com")}
- * syntax. If you do not implement this but do implement {@link ConfigIncluder},
- * attempts to load URLs will use the default includer.
- */
-public interface ConfigIncluderURL {
- /**
- * Parses another item to be included. The returned object typically would
- * not have substitutions resolved. You can throw a ConfigException here to
- * abort parsing, or return an empty object, but may not return null.
- *
- * @param context some info about the include context
- * @param what the include statement's argument
- * @return a non-null ConfigObject
- */
- ConfigObject includeURL(ConfigIncludeContext context, URL what);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigList.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigList.java
deleted file mode 100644
index 282fb3e..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigList.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import java.util.List;
-
-/**
- * Subtype of {@link ConfigValue} representing a list value, as in JSON's
- * {@code [1,2,3]} syntax.
- *
- * <p>
- * {@code ConfigList} implements {@code java.util.List<ConfigValue>} so you can
- * use it like a regular Java list. Or call {@link #unwrapped()} to unwrap the
- * list elements into plain Java values.
- *
- * <p>
- * Like all {@link ConfigValue} subtypes, {@code ConfigList} is immutable. This
- * makes it threadsafe and you never have to create "defensive copies." The
- * mutator methods from {@link java.util.List} all throw
- * {@link java.lang.UnsupportedOperationException}.
- *
- * <p>
- * The {@link ConfigValue#valueType} method on a list returns
- * {@link ConfigValueType#LIST}.
- *
- * <p>
- * <em>Do not implement {@code ConfigList}</em>; it should only be implemented
- * by the config library. Arbitrary implementations will not work because the
- * library internals assume a specific concrete implementation. Also, this
- * interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigList extends List<ConfigValue>, ConfigValue {
-
- /**
- * Recursively unwraps the list, returning a list of plain Java values such
- * as Integer or String or whatever is in the list.
- *
- * @return a {@link java.util.List} containing plain Java objects
- */
- @Override
- List<Object> unwrapped();
-
- @Override
- ConfigList withOrigin(ConfigOrigin origin);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigLoadingStrategy.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigLoadingStrategy.java
deleted file mode 100644
index 7727708..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigLoadingStrategy.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-/**
- * This method allows you to alter default config loading strategy for all the code which
- * calls {@link ConfigFactory#load}.
- * <p>
- * Usually you don't have to implement this interface but it may be required
- * when you fixing a improperly implemented library with unavailable source code.
- * <p>
- * You have to define VM property {@code config.strategy} to replace default strategy with your own.
- */
-public interface ConfigLoadingStrategy {
- /**
- * This method must load and parse application config.
- *
- * @param parseOptions {@link ConfigParseOptions} to use
- * @return loaded config
- */
- Config parseApplicationConfig(ConfigParseOptions parseOptions);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigMemorySize.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigMemorySize.java
deleted file mode 100644
index 9ec0133..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigMemorySize.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-/**
- * An immutable class representing an amount of memory. Use
- * static factory methods such as {@link
- * ConfigMemorySize#ofBytes(long)} to create instances.
- *
- * @since 1.3.0
- */
-public final class ConfigMemorySize {
- private final long bytes;
-
- private ConfigMemorySize(long bytes) {
- if (bytes < 0) {
- throw new IllegalArgumentException("Attempt to construct ConfigMemorySize with negative number: " + bytes);
- }
- this.bytes = bytes;
- }
-
- /**
- * Constructs a ConfigMemorySize representing the given
- * number of bytes.
- *
- * @param bytes a number of bytes
- * @return an instance representing the number of bytes
- * @since 1.3.0
- */
- public static ConfigMemorySize ofBytes(long bytes) {
- return new ConfigMemorySize(bytes);
- }
-
- /**
- * Gets the size in bytes.
- *
- * @return how many bytes
- * @since 1.3.0
- */
- public long toBytes() {
- return bytes;
- }
-
- @Override
- public String toString() {
- return "ConfigMemorySize(" + bytes + ")";
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof ConfigMemorySize) {
- return ((ConfigMemorySize) other).bytes == this.bytes;
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- // in Java 8 this can become Long.hashCode(bytes)
- return Long.valueOf(bytes).hashCode();
- }
-
-}
-
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigMergeable.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigMergeable.java
deleted file mode 100644
index 4032e9f..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigMergeable.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-/**
- * Marker for types whose instances can be merged, that is {@link Config} and
- * {@link ConfigValue}. Instances of {@code Config} and {@code ConfigValue} can
- * be combined into a single new instance using the
- * {@link ConfigMergeable#withFallback withFallback()} method.
- *
- * <p>
- * <em>Do not implement this interface</em>; it should only be implemented by
- * the config library. Arbitrary implementations will not work because the
- * library internals assume a specific concrete implementation. Also, this
- * interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigMergeable {
- /**
- * Returns a new value computed by merging this value with another, with
- * keys in this value "winning" over the other one.
- *
- * <p>
- * This associative operation may be used to combine configurations from
- * multiple sources (such as multiple configuration files).
- *
- * <p>
- * The semantics of merging are described in the <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">spec
- * for HOCON</a>. Merging typically occurs when either the same object is
- * created twice in the same file, or two config files are both loaded. For
- * example:
- *
- * <pre>
- * foo = { a: 42 }
- * foo = { b: 43 }
- * </pre>
- * <p>
- * Here, the two objects are merged as if you had written:
- *
- * <pre>
- * foo = { a: 42, b: 43 }
- * </pre>
- *
- * <p>
- * Only {@link ConfigObject} and {@link Config} instances do anything in
- * this method (they need to merge the fallback keys into themselves). All
- * other values just return the original value, since they automatically
- * override any fallback. This means that objects do not merge "across"
- * non-objects; if you write
- * <code>object.withFallback(nonObject).withFallback(otherObject)</code>,
- * then <code>otherObject</code> will simply be ignored. This is an
- * intentional part of how merging works, because non-objects such as
- * strings and integers replace (rather than merging with) any prior value:
- *
- * <pre>
- * foo = { a: 42 }
- * foo = 10
- * </pre>
- * <p>
- * Here, the number 10 "wins" and the value of <code>foo</code> would be
- * simply 10. Again, for details see the spec.
- *
- * @param other an object whose keys should be used as fallbacks, if the keys
- * are not present in this one
- * @return a new object (or the original one, if the fallback doesn't get
- * used)
- */
- ConfigMergeable withFallback(ConfigMergeable other);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigObject.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigObject.java
deleted file mode 100644
index 72f3024..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigObject.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import java.util.Map;
-
-/**
- * Subtype of {@link ConfigValue} representing an object (AKA dictionary or map)
- * value, as in JSON's curly brace <code>{ "a" : 42 }</code> syntax.
- *
- * <p>
- * An object may also be viewed as a {@link Config} by calling
- * {@link ConfigObject#toConfig()}.
- *
- * <p>
- * {@code ConfigObject} implements {@code java.util.Map<String, ConfigValue>} so
- * you can use it like a regular Java map. Or call {@link #unwrapped()} to
- * unwrap the map to a map with plain Java values rather than
- * {@code ConfigValue}.
- *
- * <p>
- * Like all {@link ConfigValue} subtypes, {@code ConfigObject} is immutable.
- * This makes it threadsafe and you never have to create "defensive copies." The
- * mutator methods from {@link java.util.Map} all throw
- * {@link java.lang.UnsupportedOperationException}.
- *
- * <p>
- * The {@link ConfigValue#valueType} method on an object returns
- * {@link ConfigValueType#OBJECT}.
- *
- * <p>
- * In most cases you want to use the {@link Config} interface rather than this
- * one. Call {@link #toConfig()} to convert a {@code ConfigObject} to a
- * {@code Config}.
- *
- * <p>
- * The API for a {@code ConfigObject} is in terms of keys, while the API for a
- * {@link Config} is in terms of path expressions. Conceptually,
- * {@code ConfigObject} is a tree of maps from keys to values, while a
- * {@code Config} is a one-level map from paths to values.
- *
- * <p>
- * Use {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath} to convert
- * between path expressions and individual path elements (keys).
- *
- * <p>
- * A {@code ConfigObject} may contain null values, which will have
- * {@link ConfigValue#valueType()} equal to {@link ConfigValueType#NULL}. If
- * {@link ConfigObject#get(Object)} returns Java's null then the key was not
- * present in the parsed file (or wherever this value tree came from). If
- * {@code get("key")} returns a {@link ConfigValue} with type
- * {@code ConfigValueType#NULL} then the key was set to null explicitly in the
- * config file.
- *
- * <p>
- * <em>Do not implement interface {@code ConfigObject}</em>; it should only be
- * implemented by the config library. Arbitrary implementations will not work
- * because the library internals assume a specific concrete implementation.
- * Also, this interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigObject extends ConfigValue, Map<String, ConfigValue> {
-
- /**
- * Converts this object to a {@link Config} instance, enabling you to use
- * path expressions to find values in the object. This is a constant-time
- * operation (it is not proportional to the size of the object).
- *
- * @return a {@link Config} with this object as its root
- */
- Config toConfig();
-
- /**
- * Recursively unwraps the object, returning a map from String to whatever
- * plain Java values are unwrapped from the object's values.
- *
- * @return a {@link java.util.Map} containing plain Java objects
- */
- @Override
- Map<String, Object> unwrapped();
-
- @Override
- ConfigObject withFallback(ConfigMergeable other);
-
- /**
- * Gets a {@link ConfigValue} at the given key, or returns null if there is
- * no value. The returned {@link ConfigValue} may have
- * {@link ConfigValueType#NULL} or any other type, and the passed-in key
- * must be a key in this object (rather than a path expression).
- *
- * @param key key to look up
- * @return the value at the key or null if none
- */
- @Override
- ConfigValue get(Object key);
-
- /**
- * Clone the object with only the given key (and its children) retained; all
- * sibling keys are removed.
- *
- * @param key key to keep
- * @return a copy of the object minus all keys except the one specified
- */
- ConfigObject withOnlyKey(String key);
-
- /**
- * Clone the object with the given key removed.
- *
- * @param key key to remove
- * @return a copy of the object minus the specified key
- */
- ConfigObject withoutKey(String key);
-
- /**
- * Returns a {@code ConfigObject} based on this one, but with the given key
- * set to the given value. Does not modify this instance (since it's
- * immutable). If the key already has a value, that value is replaced. To
- * remove a value, use {@link ConfigObject#withoutKey(String)}.
- *
- * @param key key to add
- * @param value value at the new key
- * @return the new instance with the new map entry
- */
- ConfigObject withValue(String key, ConfigValue value);
-
- @Override
- ConfigObject withOrigin(ConfigOrigin origin);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigOrigin.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigOrigin.java
deleted file mode 100644
index 1bbeb2f..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigOrigin.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import java.net.URL;
-import java.util.List;
-
-/**
- * Represents the origin (such as filename and line number) of a
- * {@link ConfigValue} for use in error messages. Obtain the origin of a value
- * with {@link ConfigValue#origin}. Exceptions may have an origin, see
- * {@link ConfigException#origin}, but be careful because
- * <code>ConfigException.origin()</code> may return null.
- *
- * <p>
- * It's best to use this interface only for debugging; its accuracy is
- * "best effort" rather than guaranteed, and a potentially-noticeable amount of
- * memory could probably be saved if origins were not kept around, so in the
- * future there might be some option to discard origins.
- *
- * <p>
- * <em>Do not implement this interface</em>; it should only be implemented by
- * the config library. Arbitrary implementations will not work because the
- * library internals assume a specific concrete implementation. Also, this
- * interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigOrigin {
- /**
- * Returns a string describing the origin of a value or exception. This will
- * never return null.
- *
- * @return string describing the origin
- */
- public String description();
-
- /**
- * Returns a filename describing the origin. This will return null if the
- * origin was not a file.
- *
- * @return filename of the origin or null
- */
- public String filename();
-
- /**
- * Returns a URL describing the origin. This will return null if the origin
- * has no meaningful URL.
- *
- * @return url of the origin or null
- */
- public URL url();
-
- /**
- * Returns a classpath resource name describing the origin. This will return
- * null if the origin was not a classpath resource.
- *
- * @return resource name of the origin or null
- */
- public String resource();
-
- /**
- * Returns a line number where the value or exception originated. This will
- * return -1 if there's no meaningful line number.
- *
- * @return line number or -1 if none is available
- */
- public int lineNumber();
-
- /**
- * Returns any comments that appeared to "go with" this place in the file.
- * Often an empty list, but never null. The details of this are subject to
- * change, but at the moment comments that are immediately before an array
- * element or object field, with no blank line after the comment, "go with"
- * that element or field.
- *
- * @return any comments that seemed to "go with" this origin, empty list if
- * none
- */
- public List<String> comments();
-
- /**
- * Returns a {@code ConfigOrigin} based on this one, but with the given
- * comments. Does not modify this instance or any {@code ConfigValue}s with
- * this origin (since they are immutable). To set the returned origin to a
- * {@code ConfigValue}, use {@link ConfigValue#withOrigin}.
- *
- * <p>
- * Note that when the given comments are equal to the comments on this object,
- * a new instance may not be created and {@code this} is returned directly.
- *
- * @param comments the comments used on the returned origin
- * @return the ConfigOrigin with the given comments
- * @since 1.3.0
- */
- public ConfigOrigin withComments(List<String> comments);
-
- /**
- * Returns a {@code ConfigOrigin} based on this one, but with the given
- * line number. This origin must be a FILE, URL or RESOURCE. Does not modify
- * this instance or any {@code ConfigValue}s with this origin (since they are
- * immutable). To set the returned origin to a {@code ConfigValue}, use
- * {@link ConfigValue#withOrigin}.
- *
- * <p>
- * Note that when the given lineNumber are equal to the lineNumber on this
- * object, a new instance may not be created and {@code this} is returned
- * directly.
- *
- * @param lineNumber the new line number
- * @return the created ConfigOrigin
- * @since 1.3.0
- */
- public ConfigOrigin withLineNumber(int lineNumber);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigOriginFactory.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigOriginFactory.java
deleted file mode 100644
index 7bdd5a3..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigOriginFactory.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import org.apache.seatunnel.config.impl.ConfigImpl;
-
-import java.net.URL;
-
-/**
- * This class contains some static factory methods for building a {@link
- * ConfigOrigin}. {@code ConfigOrigin}s are automatically created when you
- * call other API methods to get a {@code ConfigValue} or {@code Config}.
- * But you can also set the origin of an existing {@code ConfigValue}, using
- * {@link ConfigValue#withOrigin(ConfigOrigin)}.
- *
- * @since 1.3.0
- */
-public final class ConfigOriginFactory {
- private ConfigOriginFactory() {
- }
-
- /**
- * Returns the default origin for values when no other information is
- * provided. This is the origin used in {@link ConfigValueFactory
- * #fromAnyRef(Object)}.
- *
- * @return the default origin
- * @since 1.3.0
- */
- public static ConfigOrigin newSimple() {
- return newSimple(null);
- }
-
- /**
- * Returns an origin with the given description.
- *
- * @param description brief description of what the origin is
- * @return a new origin
- * @since 1.3.0
- */
- public static ConfigOrigin newSimple(String description) {
- return ConfigImpl.newSimpleOrigin(description);
- }
-
- /**
- * Creates a file origin with the given filename.
- *
- * @param filename the filename of this origin
- * @return a new origin
- * @since 1.3.0
- */
- public static ConfigOrigin newFile(String filename) {
- return ConfigImpl.newFileOrigin(filename);
- }
-
- /**
- * Creates a url origin with the given URL object.
- *
- * @param url the url of this origin
- * @return a new origin
- * @since 1.3.0
- */
- public static ConfigOrigin newURL(URL url) {
- return ConfigImpl.newURLOrigin(url);
- }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigParseable.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigParseable.java
deleted file mode 100644
index 5296d47..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigParseable.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-/**
- * An opaque handle to something that can be parsed, obtained from
- * {@link ConfigIncludeContext}.
- *
- * <p>
- * <em>Do not implement this interface</em>; it should only be implemented by
- * the config library. Arbitrary implementations will not work because the
- * library internals assume a specific concrete implementation. Also, this
- * interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigParseable {
- /**
- * Parse whatever it is. The options should come from
- * {@link ConfigParseable#options options()} but you could tweak them if you
- * like.
- *
- * @param options parse options, should be based on the ones from
- * {@link ConfigParseable#options options()}
- * @return the parsed object
- */
- ConfigObject parse(ConfigParseOptions options);
-
- /**
- * Returns a {@link ConfigOrigin} describing the origin of the parseable
- * item.
- *
- * @return the origin of the parseable item
- */
- ConfigOrigin origin();
-
- /**
- * Get the initial options, which can be modified then passed to parse().
- * These options will have the right description, includer, and other
- * parameters already set up.
- *
- * @return the initial options
- */
- ConfigParseOptions options();
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigRenderOptions.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigRenderOptions.java
deleted file mode 100644
index c3e311f..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigRenderOptions.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-/**
- * <p>
- * A set of options related to rendering a {@link ConfigValue}. Passed to
- * {@link ConfigValue#render(ConfigRenderOptions)}.
- *
- * <p>
- * Here is an example of creating a {@code ConfigRenderOptions}:
- *
- * <pre>
- * ConfigRenderOptions options =
- * ConfigRenderOptions.defaults().setComments(false)
- * </pre>
- */
-public final class ConfigRenderOptions {
- private final boolean originComments;
- private final boolean comments;
- private final boolean formatted;
- private final boolean json;
-
- private ConfigRenderOptions(boolean originComments, boolean comments, boolean formatted,
- boolean json) {
- this.originComments = originComments;
- this.comments = comments;
- this.formatted = formatted;
- this.json = json;
- }
-
- /**
- * Returns the default render options which are verbose (commented and
- * formatted). See {@link ConfigRenderOptions#concise} for stripped-down
- * options. This rendering will not be valid JSON since it has comments.
- *
- * @return the default render options
- */
- public static ConfigRenderOptions defaults() {
- return new ConfigRenderOptions(true, true, true, true);
- }
-
- /**
- * Returns concise render options (no whitespace or comments). For a
- * resolved {@link Config}, the concise rendering will be valid JSON.
- *
- * @return the concise render options
- */
- public static ConfigRenderOptions concise() {
- return new ConfigRenderOptions(false, false, false, true);
- }
-
- /**
- * Returns options with comments toggled. This controls human-written
- * comments but not the autogenerated "origin of this setting" comments,
- * which are controlled by {@link ConfigRenderOptions#setOriginComments}.
- *
- * @param value true to include comments in the render
- * @return options with requested setting for comments
- */
- public ConfigRenderOptions setComments(boolean value) {
- if (value == comments) {
- return this;
- }
- return new ConfigRenderOptions(originComments, value, formatted, json);
- }
-
- /**
- * Returns whether the options enable comments. This method is mostly used
- * by the config lib internally, not by applications.
- *
- * @return true if comments should be rendered
- */
- public boolean getComments() {
- return comments;
- }
-
- /**
- * Returns options with origin comments toggled. If this is enabled, the
- * library generates comments for each setting based on the
- * {@link ConfigValue#origin} of that setting's value. For example these
- * comments might tell you which file a setting comes from.
- *
- * <p>
- * {@code setOriginComments()} controls only these autogenerated
- * "origin of this setting" comments, to toggle regular comments use
- * {@link ConfigRenderOptions#setComments}.
- *
- * @param value true to include autogenerated setting-origin comments in the
- * render
- * @return options with origin comments toggled
- */
- public ConfigRenderOptions setOriginComments(boolean value) {
- if (value == originComments) {
- return this;
- }
- return new ConfigRenderOptions(value, comments, formatted, json);
- }
-
- /**
- * Returns whether the options enable automated origin comments. This method
- * is mostly used by the config lib internally, not by applications.
- *
- * @return true if origin comments should be rendered
- */
- public boolean getOriginComments() {
- return originComments;
- }
-
- /**
- * Returns options with formatting toggled. Formatting means indentation and
- * whitespace, enabling formatting makes things prettier but larger.
- *
- * @param value true to enable formatting
- * @return options with requested setting for formatting
- */
- public ConfigRenderOptions setFormatted(boolean value) {
- if (value == formatted) {
- return this;
- }
- return new ConfigRenderOptions(originComments, comments, value, json);
- }
-
- /**
- * Returns whether the options enable formatting. This method is mostly used
- * by the config lib internally, not by applications.
- *
- * @return true if the options enable formatting
- */
- public boolean getFormatted() {
- return formatted;
- }
-
- /**
- * Returns options with JSON toggled. JSON means that HOCON extensions
- * (omitting commas, quotes for example) won't be used. However, whether to
- * use comments is controlled by the separate {@link #setComments(boolean)}
- * and {@link #setOriginComments(boolean)} options. So if you enable
- * comments you will get invalid JSON despite setting this to true.
- *
- * @param value true to include non-JSON extensions in the render
- * @return options with requested setting for JSON
- */
- public ConfigRenderOptions setJson(boolean value) {
- if (value == json) {
- return this;
- }
- return new ConfigRenderOptions(originComments, comments, formatted, value);
- }
-
- /**
- * Returns whether the options enable JSON. This method is mostly used by
- * the config lib internally, not by applications.
- *
- * @return true if only JSON should be rendered
- */
- public boolean getJson() {
- return json;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("ConfigRenderOptions(");
- if (originComments) {
- sb.append("originComments,");
- }
- if (comments) {
- sb.append("comments,");
- }
- if (formatted) {
- sb.append("formatted,");
- }
- if (json) {
- sb.append("json,");
- }
- if (sb.charAt(sb.length() - 1) == ',') {
- sb.setLength(sb.length() - 1);
- }
- sb.append(")");
- return sb.toString();
- }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigResolveOptions.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigResolveOptions.java
deleted file mode 100644
index eaa0022..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigResolveOptions.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-/**
- * A set of options related to resolving substitutions. Substitutions use the
- * <code>${foo.bar}</code> syntax and are documented in the <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">HOCON</a>
- * spec.
- * <p>
- * Typically this class would be used with the method
- * {@link Config#resolve(ConfigResolveOptions)}.
- * <p>
- * This object is immutable, so the "setters" return a new object.
- * <p>
- * Here is an example of creating a custom {@code ConfigResolveOptions}:
- *
- * <pre>
- * ConfigResolveOptions options = ConfigResolveOptions.defaults()
- * .setUseSystemEnvironment(false)
- * </pre>
- * <p>
- * In addition to {@link ConfigResolveOptions#defaults}, there's a prebuilt
- * {@link ConfigResolveOptions#noSystem} which avoids looking at any system
- * environment variables or other external system information. (Right now,
- * environment variables are the only example.)
- */
-public final class ConfigResolveOptions {
- private final boolean useSystemEnvironment;
- private final boolean allowUnresolved;
- private final ConfigResolver resolver;
-
- private ConfigResolveOptions(boolean useSystemEnvironment, boolean allowUnresolved,
- ConfigResolver resolver) {
- this.useSystemEnvironment = useSystemEnvironment;
- this.allowUnresolved = allowUnresolved;
- this.resolver = resolver;
- }
-
- /**
- * Returns the default resolve options. By default the system environment
- * will be used and unresolved substitutions are not allowed.
- *
- * @return the default resolve options
- */
- public static ConfigResolveOptions defaults() {
- return new ConfigResolveOptions(true, false, NULL_RESOLVER);
- }
-
- /**
- * Returns resolve options that disable any reference to "system" data
- * (currently, this means environment variables).
- *
- * @return the resolve options with env variables disabled
- */
- public static ConfigResolveOptions noSystem() {
- return defaults().setUseSystemEnvironment(false);
- }
-
- /**
- * Returns options with use of environment variables set to the given value.
- *
- * @param value true to resolve substitutions falling back to environment
- * variables.
- * @return options with requested setting for use of environment variables
- */
- public ConfigResolveOptions setUseSystemEnvironment(boolean value) {
- return new ConfigResolveOptions(value, allowUnresolved, resolver);
- }
-
- /**
- * Returns whether the options enable use of system environment variables.
- * This method is mostly used by the config lib internally, not by
- * applications.
- *
- * @return true if environment variables should be used
- */
- public boolean getUseSystemEnvironment() {
- return useSystemEnvironment;
- }
-
- /**
- * Returns options with "allow unresolved" set to the given value. By
- * default, unresolved substitutions are an error. If unresolved
- * substitutions are allowed, then a future attempt to use the unresolved
- * value may fail, but {@link Config#resolve(ConfigResolveOptions)} itself
- * will not throw.
- *
- * @param value true to silently ignore unresolved substitutions.
- * @return options with requested setting for whether to allow substitutions
- * @since 1.2.0
- */
- public ConfigResolveOptions setAllowUnresolved(boolean value) {
- return new ConfigResolveOptions(useSystemEnvironment, value, resolver);
- }
-
- /**
- * Returns options where the given resolver used as a fallback if a
- * reference cannot be otherwise resolved. This resolver will only be called
- * after resolution has failed to substitute with a value from within the
- * config itself and with any other resolvers that have been appended before
- * this one. Multiple resolvers can be added using,
- *
- * <pre>
- * ConfigResolveOptions options = ConfigResolveOptions.defaults()
- * .appendResolver(primary)
- * .appendResolver(secondary)
- * .appendResolver(tertiary);
- * </pre>
- * <p>
- * With this config unresolved references will first be resolved with the
- * primary resolver, if that fails then the secondary, and finally if that
- * also fails the tertiary.
- * <p>
- * If all fallbacks fail to return a substitution "allow unresolved"
- * determines whether resolution fails or continues.
- * `
- *
- * @param value the resolver to fall back to
- * @return options that use the given resolver as a fallback
- * @since 1.3.2
- */
- public ConfigResolveOptions appendResolver(ConfigResolver value) {
- if (value == null) {
- throw new ConfigException.BugOrBroken("null resolver passed to appendResolver");
- } else if (value == this.resolver) {
- return this;
- }
- return new ConfigResolveOptions(useSystemEnvironment, allowUnresolved,
- this.resolver.withFallback(value));
- }
-
- /**
- * Returns the resolver to use as a fallback if a substitution cannot be
- * otherwise resolved. Never returns null. This method is mostly used by the
- * config lib internally, not by applications.
- *
- * @return the non-null fallback resolver
- * @since 1.3.2
- */
- public ConfigResolver getResolver() {
- return this.resolver;
- }
-
- /**
- * Returns whether the options allow unresolved substitutions. This method
- * is mostly used by the config lib internally, not by applications.
- *
- * @return true if unresolved substitutions are allowed
- * @since 1.2.0
- */
- public boolean getAllowUnresolved() {
- return allowUnresolved;
- }
-
- /**
- * Singleton resolver that never resolves paths.
- */
- private static final ConfigResolver NULL_RESOLVER = new ConfigResolver() {
-
- @Override
- public ConfigValue lookup(String path) {
- return null;
- }
-
- @Override
- public ConfigResolver withFallback(ConfigResolver fallback) {
- return fallback;
- }
-
- };
-
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigResolver.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigResolver.java
deleted file mode 100644
index fe68f41..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigResolver.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-/**
- * Implement this interface and provide an instance to
- * {@link ConfigResolveOptions#appendResolver ConfigResolveOptions.appendResolver()}
- * to provide custom behavior when unresolved substitutions are encountered
- * during resolution.
- *
- * @since 1.3.2
- */
-public interface ConfigResolver {
-
- /**
- * Returns the value to substitute for the given unresolved path. To get the
- * components of the path use {@link ConfigUtil#splitPath(String)}. If a
- * non-null value is returned that value will be substituted, otherwise
- * resolution will continue to consider the substitution as still
- * unresolved.
- *
- * @param path the unresolved path
- * @return the value to use as a substitution or null
- */
- public ConfigValue lookup(String path);
-
- /**
- * Returns a new resolver that falls back to the given resolver if this
- * one doesn't provide a substitution itself.
- * <p>
- * It's important to handle the case where you already have the fallback
- * with a "return this", i.e. this method should not create a new object if
- * the fallback is the same one you already have. The same fallback may be
- * added repeatedly.
- *
- * @param fallback the previous includer for chaining
- * @return a new resolver
- */
- public ConfigResolver withFallback(ConfigResolver fallback);
-
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigSyntax.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigSyntax.java
deleted file mode 100644
index 6a5688e..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigSyntax.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-/**
- * The syntax of a character stream (<a href="http://json.org">JSON</a>, <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">HOCON</a>
- * aka ".conf", or <a href=
- * "http://download.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.Reader%29"
- * >Java properties</a>).
- */
-public enum ConfigSyntax {
- /**
- * Pedantically strict <a href="http://json.org">JSON</a> format; no
- * comments, no unexpected commas, no duplicate keys in the same object.
- * Associated with the <code>.json</code> file extension and
- * <code>application/json</code> Content-Type.
- */
- JSON,
- /**
- * The JSON-superset <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md"
- * >HOCON</a> format. Associated with the <code>.conf</code> file extension
- * and <code>application/hocon</code> Content-Type.
- */
- CONF,
- /**
- * Standard <a href=
- * "http://download.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.Reader%29"
- * >Java properties</a> format. Associated with the <code>.properties</code>
- * file extension and <code>text/x-java-properties</code> Content-Type.
- */
- PROPERTIES;
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigUtil.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigUtil.java
deleted file mode 100644
index dacdefe..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigUtil.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import org.apache.seatunnel.config.impl.ConfigImplUtil;
-
-import java.util.List;
-
-/**
- * Contains static utility methods.
- */
-public final class ConfigUtil {
- private ConfigUtil() {
-
- }
-
- /**
- * Quotes and escapes a string, as in the JSON specification.
- *
- * @param s a string
- * @return the string quoted and escaped
- */
- public static String quoteString(String s) {
- return ConfigImplUtil.renderJsonString(s);
- }
-
- /**
- * Converts a list of keys to a path expression, by quoting the path
- * elements as needed and then joining them separated by a period. A path
- * expression is usable with a {@link Config}, while individual path
- * elements are usable with a {@link ConfigObject}.
- * <p>
- * See the overview documentation for {@link Config} for more detail on path
- * expressions vs. keys.
- *
- * @param elements the keys in the path
- * @return a path expression
- * @throws ConfigException if there are no elements
- */
- public static String joinPath(String... elements) {
- return ConfigImplUtil.joinPath(elements);
- }
-
- /**
- * Converts a list of strings to a path expression, by quoting the path
- * elements as needed and then joining them separated by a period. A path
- * expression is usable with a {@link Config}, while individual path
- * elements are usable with a {@link ConfigObject}.
- * <p>
- * See the overview documentation for {@link Config} for more detail on path
- * expressions vs. keys.
- *
- * @param elements the keys in the path
- * @return a path expression
- * @throws ConfigException if the list is empty
- */
- public static String joinPath(List<String> elements) {
- return ConfigImplUtil.joinPath(elements);
- }
-
- /**
- * Converts a path expression into a list of keys, by splitting on period
- * and unquoting the individual path elements. A path expression is usable
- * with a {@link Config}, while individual path elements are usable with a
- * {@link ConfigObject}.
- * <p>
- * See the overview documentation for {@link Config} for more detail on path
- * expressions vs. keys.
- *
- * @param path a path expression
- * @return the individual keys in the path
- * @throws ConfigException if the path expression is invalid
- */
- public static List<String> splitPath(String path) {
- return ConfigImplUtil.splitPath(path);
- }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValue.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValue.java
deleted file mode 100644
index b5c3152..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValue.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-/**
- * An immutable value, following the <a href="http://json.org">JSON</a> type
- * schema.
- *
- * <p>
- * Because this object is immutable, it is safe to use from multiple threads and
- * there's no need for "defensive copies."
- *
- * <p>
- * <em>Do not implement interface {@code ConfigValue}</em>; it should only be
- * implemented by the config library. Arbitrary implementations will not work
- * because the library internals assume a specific concrete implementation.
- * Also, this interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigValue extends ConfigMergeable {
- /**
- * The origin of the value (file, line number, etc.), for debugging and
- * error messages.
- *
- * @return where the value came from
- */
- ConfigOrigin origin();
-
- /**
- * The {@link ConfigValueType} of the value; matches the JSON type schema.
- *
- * @return value's type
- */
- ConfigValueType valueType();
-
- /**
- * Returns the value as a plain Java boxed value, that is, a {@code String},
- * {@code Number}, {@code Boolean}, {@code Map<String,Object>},
- * {@code List<Object>}, or {@code null}, matching the {@link #valueType()}
- * of this {@code ConfigValue}. If the value is a {@link ConfigObject} or
- * {@link ConfigList}, it is recursively unwrapped.
- *
- * @return a plain Java value corresponding to this ConfigValue
- */
- Object unwrapped();
-
- /**
- * Renders the config value as a HOCON string. This method is primarily
- * intended for debugging, so it tries to add helpful comments and
- * whitespace.
- *
- * <p>
- * If the config value has not been resolved (see {@link Config#resolve}),
- * it's possible that it can't be rendered as valid HOCON. In that case the
- * rendering should still be useful for debugging but you might not be able
- * to parse it. If the value has been resolved, it will always be parseable.
- *
- * <p>
- * This method is equivalent to
- * {@code render(ConfigRenderOptions.defaults())}.
- *
- * @return the rendered value
- */
- String render();
-
- /**
- * Renders the config value to a string, using the provided options.
- *
- * <p>
- * If the config value has not been resolved (see {@link Config#resolve}),
- * it's possible that it can't be rendered as valid HOCON. In that case the
- * rendering should still be useful for debugging but you might not be able
- * to parse it. If the value has been resolved, it will always be parseable.
- *
- * <p>
- * If the config value has been resolved and the options disable all
- * HOCON-specific features (such as comments), the rendering will be valid
- * JSON. If you enable HOCON-only features such as comments, the rendering
- * will not be valid JSON.
- *
- * @param options the rendering options
- * @return the rendered value
- */
- String render(ConfigRenderOptions options);
-
- @Override
- ConfigValue withFallback(ConfigMergeable other);
-
- /**
- * Places the value inside a {@link Config} at the given path. See also
- * {@link ConfigValue#atKey(String)}.
- *
- * @param path path to store this value at.
- * @return a {@code Config} instance containing this value at the given
- * path.
- */
- Config atPath(String path);
-
- /**
- * Places the value inside a {@link Config} at the given key. See also
- * {@link ConfigValue#atPath(String)}.
- *
- * @param key key to store this value at.
- * @return a {@code Config} instance containing this value at the given key.
- */
- Config atKey(String key);
-
- /**
- * Returns a {@code ConfigValue} based on this one, but with the given
- * origin. This is useful when you are parsing a new format of file or setting
- * comments for a single ConfigValue.
- *
- * @param origin the origin set on the returned value
- * @return the new ConfigValue with the given origin
- * @since 1.3.0
- */
- ConfigValue withOrigin(ConfigOrigin origin);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValueFactory.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValueFactory.java
deleted file mode 100644
index cd33591..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValueFactory.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import org.apache.seatunnel.config.impl.ConfigImpl;
-
-import java.util.Map;
-
-/**
- * This class holds some static factory methods for building {@link ConfigValue}
- * instances. See also {@link ConfigFactory} which has methods for parsing files
- * and certain in-memory data structures.
- */
-public final class ConfigValueFactory {
- private ConfigValueFactory() {
- }
-
- /**
- * Creates a {@link ConfigValue} from a plain Java boxed value, which may be
- * a <code>Boolean</code>, <code>Number</code>, <code>String</code>,
- * <code>Map</code>, <code>Iterable</code>, or <code>null</code>. A
- * <code>Map</code> must be a <code>Map</code> from String to more values
- * that can be supplied to <code>fromAnyRef()</code>. An
- * <code>Iterable</code> must iterate over more values that can be supplied
- * to <code>fromAnyRef()</code>. A <code>Map</code> will become a
- * {@link ConfigObject} and an <code>Iterable</code> will become a
- * {@link ConfigList}. If the <code>Iterable</code> is not an ordered
- * collection, results could be strange, since <code>ConfigList</code> is
- * ordered.
- *
- * <p>
- * In a <code>Map</code> passed to <code>fromAnyRef()</code>, the map's keys
- * are plain keys, not path expressions. So if your <code>Map</code> has a
- * key "foo.bar" then you will get one object with a key called "foo.bar",
- * rather than an object with a key "foo" containing another object with a
- * key "bar".
- *
- * <p>
- * The originDescription will be used to set the origin() field on the
- * ConfigValue. It should normally be the name of the file the values came
- * from, or something short describing the value such as "default settings".
- * The originDescription is prefixed to error messages so users can tell
- * where problematic values are coming from.
- *
- * <p>
- * Supplying the result of ConfigValue.unwrapped() to this function is
- * guaranteed to work and should give you back a ConfigValue that matches
- * the one you unwrapped. The re-wrapped ConfigValue will lose some
- * information that was present in the original such as its origin, but it
- * will have matching values.
- *
- * <p>
- * If you pass in a <code>ConfigValue</code> to this
- * function, it will be returned unmodified. (The
- * <code>originDescription</code> will be ignored in this
- * case.)
- *
- * <p>
- * This function throws if you supply a value that cannot be converted to a
- * ConfigValue, but supplying such a value is a bug in your program, so you
- * should never handle the exception. Just fix your program (or report a bug
- * against this library).
- *
- * @param object object to convert to ConfigValue
- * @param originDescription name of origin file or brief description of what the value is
- * @return a new value
- */
- public static ConfigValue fromAnyRef(Object object, String originDescription) {
- return ConfigImpl.fromAnyRef(object, originDescription);
- }
-
- /**
- * See the {@link #fromAnyRef(Object, String)} documentation for details.
- * This is a typesafe wrapper that only works on {@link java.util.Map} and
- * returns {@link ConfigObject} rather than {@link ConfigValue}.
- *
- * <p>
- * If your <code>Map</code> has a key "foo.bar" then you will get one object
- * with a key called "foo.bar", rather than an object with a key "foo"
- * containing another object with a key "bar". The keys in the map are keys;
- * not path expressions. That is, the <code>Map</code> corresponds exactly
- * to a single {@code ConfigObject}. The keys will not be parsed or
- * modified, and the values are wrapped in ConfigValue. To get nested
- * {@code ConfigObject}, some of the values in the map would have to be more
- * maps.
- *
- * <p>
- * See also {@link ConfigFactory#parseMap(Map, String)} which interprets the
- * keys in the map as path expressions.
- *
- * @param values map from keys to plain Java values
- * @param originDescription description to use in {@link ConfigOrigin} of created values
- * @return a new {@link ConfigObject} value
- */
- public static ConfigObject fromMap(Map<String, ? extends Object> values,
- String originDescription) {
- return (ConfigObject) fromAnyRef(values, originDescription);
- }
-
- /**
- * See the {@link #fromAnyRef(Object, String)} documentation for details.
- * This is a typesafe wrapper that only works on {@link java.lang.Iterable}
- * and returns {@link ConfigList} rather than {@link ConfigValue}.
- *
- * @param values list of plain Java values
- * @param originDescription description to use in {@link ConfigOrigin} of created values
- * @return a new {@link ConfigList} value
- */
- public static ConfigList fromIterable(Iterable<? extends Object> values,
- String originDescription) {
- return (ConfigList) fromAnyRef(values, originDescription);
- }
-
- /**
- * See the other overload {@link #fromAnyRef(Object, String)} for details,
- * this one just uses a default origin description.
- *
- * @param object a plain Java value
- * @return a new {@link ConfigValue}
- */
- public static ConfigValue fromAnyRef(Object object) {
- return fromAnyRef(object, null);
- }
-
- /**
- * See the other overload {@link #fromMap(Map, String)} for details, this one
- * just uses a default origin description.
- *
- * <p>
- * See also {@link ConfigFactory#parseMap(Map)} which interprets the keys in
- * the map as path expressions.
- *
- * @param values map from keys to plain Java values
- * @return a new {@link ConfigObject}
- */
- public static ConfigObject fromMap(Map<String, ? extends Object> values) {
- return fromMap(values, null);
- }
-
- /**
- * See the other overload of {@link #fromIterable(Iterable, String)} for
- * details, this one just uses a default origin description.
- *
- * @param values list of plain Java values
- * @return a new {@link ConfigList}
- */
- public static ConfigList fromIterable(Iterable<? extends Object> values) {
- return fromIterable(values, null);
- }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValueType.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValueType.java
deleted file mode 100644
index b32d771..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValueType.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-/**
- * The type of a configuration value (following the <a
- * href="http://json.org">JSON</a> type schema).
- */
-public enum ConfigValueType {
- OBJECT, LIST, NUMBER, BOOLEAN, NULL, STRING
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/DefaultConfigLoadingStrategy.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/DefaultConfigLoadingStrategy.java
deleted file mode 100644
index 583d43e..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/DefaultConfigLoadingStrategy.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * Default config loading strategy. Able to load resource, file or URL.
- * Behavior may be altered by defining one of VM properties
- * {@code config.resource}, {@code config.file} or {@code config.url}
- */
-public class DefaultConfigLoadingStrategy implements ConfigLoadingStrategy {
- @Override
- public Config parseApplicationConfig(ConfigParseOptions parseOptions) {
- ClassLoader loader = parseOptions.getClassLoader();
- if (loader == null) {
- throw new ConfigException.BugOrBroken(
- "ClassLoader should have been set here; bug in ConfigFactory. " + "(You can probably work around this bug by passing in a class loader or calling currentThread().setContextClassLoader() though.)");
- }
-
- int specified = 0;
-
- // override application.conf with config.file, config.resource,
- // config.url if requested.
- String resource = System.getProperty("config.resource");
- if (resource != null) {
- specified += 1;
- }
- String file = System.getProperty("config.file");
- if (file != null) {
- specified += 1;
- }
- String url = System.getProperty("config.url");
- if (url != null) {
- specified += 1;
- }
-
- if (specified == 0) {
- return ConfigFactory.parseResourcesAnySyntax("application", parseOptions);
- } else if (specified > 1) {
- throw new ConfigException.Generic("You set more than one of config.file='"
- + file + "', config.url='"
- + url + "', config.resource='"
- + resource + "'; don't know which one to use!");
- }
- // the override file/url/resource MUST be present or it's an error
- ConfigParseOptions overrideOptions = parseOptions.setAllowMissing(false);
- if (resource != null) {
- if (resource.startsWith("/")) {
- resource = resource.substring(1);
- }
- // this deliberately does not parseResourcesAnySyntax; if
- // people want that they can use an include statement.
- return ConfigFactory.parseResources(loader, resource, overrideOptions);
- } else if (file != null) {
- return ConfigFactory.parseFile(new File(file), overrideOptions);
- }
- try {
- return ConfigFactory.parseURL(new URL(url), overrideOptions);
- } catch (MalformedURLException e) {
- throw new ConfigException.Generic("Bad URL in config.url system property: '"
- + url + "': " + e.getMessage(), e);
- }
- }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/Optional.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/Optional.java
deleted file mode 100644
index ab16a1a..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/Optional.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Allows an config property to be {@code null}.
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Optional {
-
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigNode.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigNode.java
deleted file mode 100644
index d20026b..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigNode.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.parser.ConfigNode;
-
-import java.util.Collection;
-
-abstract class AbstractConfigNode implements ConfigNode {
- abstract Collection<Token> tokens();
-
- @Override
- public final String render() {
- StringBuilder origText = new StringBuilder();
- Iterable<Token> tokens = tokens();
- for (Token t : tokens) {
- origText.append(t.tokenText());
- }
- return origText.toString();
- }
-
- @Override
- public final boolean equals(Object other) {
- return other instanceof AbstractConfigNode && render().equals(((AbstractConfigNode) other).render());
- }
-
- @Override
- public final int hashCode() {
- return render().hashCode();
- }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigNodeValue.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigNodeValue.java
deleted file mode 100644
index 898a03b..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigNodeValue.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config.impl;
-
-// This is required if we want
-// to be referencing the AbstractConfigNode class in implementation rather than the
-// ConfigNode interface, as we can't cast an AbstractConfigNode to an interface
-abstract class AbstractConfigNodeValue extends AbstractConfigNode {
-
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigObject.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigObject.java
deleted file mode 100644
index ec95a65..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigObject.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.ConfigException.BugOrBroken;
-import org.apache.seatunnel.config.ConfigException.NotResolved;
-import org.apache.seatunnel.config.ConfigMergeable;
-import org.apache.seatunnel.config.ConfigObject;
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigRenderOptions;
-import org.apache.seatunnel.config.ConfigValue;
-import org.apache.seatunnel.config.ConfigValueType;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-abstract class AbstractConfigObject extends AbstractConfigValue implements ConfigObject, Container {
- private final SimpleConfig config;
-
- protected AbstractConfigObject(ConfigOrigin origin) {
- super(origin);
- this.config = new SimpleConfig(this);
- }
-
- @Override
- public SimpleConfig toConfig() {
- return config;
- }
-
- @Override
- public AbstractConfigObject toFallbackValue() {
- return this;
- }
-
- @Override
- public abstract AbstractConfigObject withOnlyKey(String key);
-
- @Override
- public abstract AbstractConfigObject withoutKey(String key);
-
- @Override
- public abstract AbstractConfigObject withValue(String key, ConfigValue value);
-
- protected abstract AbstractConfigObject withOnlyPathOrNull(Path path);
-
- abstract AbstractConfigObject withOnlyPath(Path path);
-
- abstract AbstractConfigObject withoutPath(Path path);
-
- abstract AbstractConfigObject withValue(Path path, ConfigValue value);
-
- /**
- * This looks up the key with no transformation or type conversion of any
- * kind, and returns null if the key is not present. The object must be
- * resolved along the nodes needed to get the key or
- * ConfigException.NotResolved will be thrown.
- *
- * @param key key
- * @return the unmodified raw value or null
- */
- protected final AbstractConfigValue peekAssumingResolved(String key, Path originalPath) {
- try {
- return attemptPeekWithPartialResolve(key);
- } catch (NotResolved e) {
- throw ConfigImpl.improveNotResolved(originalPath, e);
- }
- }
-
- /**
- * Look up the key on an only-partially-resolved object, with no
- * transformation or type conversion of any kind; if 'this' is not resolved
- * then try to look up the key anyway if possible.
- *
- * @param key key to look up
- * @return the value of the key, or null if known not to exist
- * @throws NotResolved if can't figure out key's value (or existence) without more
- * resolving
- */
- abstract AbstractConfigValue attemptPeekWithPartialResolve(String key);
-
- /**
- * Looks up the path with no transformation or type conversion. Returns null
- * if the path is not found; throws ConfigException.NotResolved if we need
- * to go through an unresolved node to look up the path.
- */
- protected AbstractConfigValue peekPath(Path path) {
- return peekPath(this, path);
- }
-
- private static AbstractConfigValue peekPath(AbstractConfigObject self, Path path) {
- try {
- // we'll fail if anything along the path can't
- // be looked at without resolving.
- Path next = path.remainder();
- AbstractConfigValue v = self.attemptPeekWithPartialResolve(path.first());
-
- if (next == null) {
- return v;
- }
- if (v instanceof AbstractConfigObject) {
- return peekPath((AbstractConfigObject) v, next);
- }
- return null;
- } catch (NotResolved e) {
- throw ConfigImpl.improveNotResolved(path, e);
- }
- }
-
- @Override
- public ConfigValueType valueType() {
- return ConfigValueType.OBJECT;
- }
-
- protected abstract AbstractConfigObject newCopy(ResolveStatus status, ConfigOrigin origin);
-
- @Override
- protected AbstractConfigObject newCopy(ConfigOrigin origin) {
- return newCopy(resolveStatus(), origin);
- }
-
- @Override
- protected AbstractConfigObject constructDelayedMerge(ConfigOrigin origin,
- List<AbstractConfigValue> stack) {
- return new ConfigDelayedMergeObject(origin, stack);
- }
-
- @Override
- protected abstract AbstractConfigObject mergedWithObject(AbstractConfigObject fallback);
-
- @Override
- public AbstractConfigObject withFallback(ConfigMergeable mergeable) {
- return (AbstractConfigObject) super.withFallback(mergeable);
- }
-
- static ConfigOrigin mergeOrigins(
- Collection<? extends AbstractConfigValue> stack) {
- if (stack.isEmpty()) {
- throw new BugOrBroken(
- "can't merge origins on empty list");
- }
- List<ConfigOrigin> origins = new ArrayList<ConfigOrigin>();
- ConfigOrigin firstOrigin = null;
- int numMerged = 0;
- for (AbstractConfigValue v : stack) {
- if (firstOrigin == null) {
- firstOrigin = v.origin();
- }
-
- if (v instanceof AbstractConfigObject
- && ((AbstractConfigObject) v).resolveStatus() == ResolveStatus.RESOLVED
- && ((ConfigObject) v).isEmpty()) {
- // don't include empty files or the .empty()
- // config in the description, since they are
- // likely to be "implementation details"
- } else {
- origins.add(v.origin());
- numMerged += 1;
- }
- }
-
- if (numMerged == 0) {
- // the configs were all empty, so just use the first one
- origins.add(firstOrigin);
- }
-
- return SimpleConfigOrigin.mergeOrigins(origins);
- }
-
- static ConfigOrigin mergeOrigins(AbstractConfigObject... stack) {
- return mergeOrigins(Arrays.asList(stack));
- }
-
- @Override
- abstract ResolveResult<? extends AbstractConfigObject> resolveSubstitutions(ResolveContext context,
- ResolveSource source)
- throws NotPossibleToResolve;
-
- @Override
- abstract AbstractConfigObject relativized(final Path prefix);
-
- @Override
- public abstract AbstractConfigValue get(Object key);
-
- @Override
- protected abstract void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options);
-
- private static UnsupportedOperationException weAreImmutable(String method) {
- return new UnsupportedOperationException("ConfigObject is immutable, you can't call Map." + method);
- }
-
- @Override
- public void clear() {
- throw weAreImmutable("clear");
- }
-
- @Override
- public ConfigValue put(String arg0, ConfigValue arg1) {
- throw weAreImmutable("put");
- }
-
- @Override
- public void putAll(Map<? extends String, ? extends ConfigValue> arg0) {
- throw weAreImmutable("putAll");
- }
-
- @Override
- public ConfigValue remove(Object arg0) {
- throw weAreImmutable("remove");
- }
-
- @Override
- public AbstractConfigObject withOrigin(ConfigOrigin origin) {
- return (AbstractConfigObject) super.withOrigin(origin);
- }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigValue.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigValue.java
deleted file mode 100644
index 866bfa7..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigValue.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.ConfigException.BugOrBroken;
-import org.apache.seatunnel.config.ConfigMergeable;
-import org.apache.seatunnel.config.ConfigObject;
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigRenderOptions;
-import org.apache.seatunnel.config.ConfigValue;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Trying very hard to avoid a parent reference in config values; when you have
- * a tree like this, the availability of parent() tends to result in a lot of
- * improperly-factored and non-modular code. Please don't add parent().
- */
-abstract class AbstractConfigValue implements ConfigValue, MergeableValue {
-
- private final SimpleConfigOrigin origin;
-
- AbstractConfigValue(ConfigOrigin origin) {
- this.origin = (SimpleConfigOrigin) origin;
- }
-
- @Override
- public SimpleConfigOrigin origin() {
- return this.origin;
- }
-
- /**
- * This exception means that a value is inherently not resolveable, at the
- * moment the only known cause is a cycle of substitutions. This is a
- * checked exception since it's internal to the library and we want to be
- * sure we handle it before passing it out to public API. This is only
- * supposed to be thrown by the target of a cyclic reference and it's
- * supposed to be caught by the ConfigReference looking up that reference,
- * so it should be impossible for an outermost resolve() to throw this.
- * <p>
- * Contrast with ConfigException.NotResolved which just means nobody called
- * resolve().
- */
- static class NotPossibleToResolve extends Exception {
- private static final long serialVersionUID = 1L;
-
- private final String traceString;
-
- NotPossibleToResolve(ResolveContext context) {
- super("was not possible to resolve");
- this.traceString = context.traceString();
- }
-
- String traceString() {
- return traceString;
- }
- }
-
- /**
- * Called only by ResolveContext.resolve().
- *
- * @param context state of the current resolve
- * @param source where to look up values
- * @return a new value if there were changes, or this if no changes
- */
- ResolveResult<? extends AbstractConfigValue> resolveSubstitutions(ResolveContext context, ResolveSource source)
- throws NotPossibleToResolve {
- return ResolveResult.make(context, this);
- }
-
- ResolveStatus resolveStatus() {
- return ResolveStatus.RESOLVED;
- }
-
- protected static List<AbstractConfigValue> replaceChildInList(List<AbstractConfigValue> list,
- AbstractConfigValue child, AbstractConfigValue replacement) {
- int i = 0;
- while (i < list.size() && list.get(i) != child) {
- ++i;
- }
- if (i == list.size()) {
- throw new BugOrBroken("tried to replace " + child + " which is not in " + list);
- }
- List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>(list);
- if (replacement != null) {
- newStack.set(i, replacement);
- } else {
- newStack.remove(i);
- }
-
- if (newStack.isEmpty()) {
- return null;
- }
- return newStack;
- }
-
- protected static boolean hasDescendantInList(List<AbstractConfigValue> list, AbstractConfigValue descendant) {
- for (AbstractConfigValue v : list) {
- if (v == descendant) {
- return true;
- }
- }
- // now the expensive traversal
- for (AbstractConfigValue v : list) {
- if (v instanceof Container && ((Container) v).hasDescendant(descendant)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * This is used when including one file in another; the included file is
- * relativized to the path it's included into in the parent file. The point
- * is that if you include a file at foo.bar in the parent, and the included
- * file as a substitution ${a.b.c}, the included substitution now needs to
- * be ${foo.bar.a.b.c} because we resolve substitutions globally only after
- * parsing everything.
- *
- * @param prefix prefix
- * @return value relativized to the given path or the same value if nothing
- * to do
- */
- AbstractConfigValue relativized(Path prefix) {
- return this;
- }
-
- protected interface Modifier {
- // keyOrNull is null for non-objects
- AbstractConfigValue modifyChildMayThrow(String keyOrNull, AbstractConfigValue v)
- throws Exception;
- }
-
- protected abstract class NoExceptionsModifier implements Modifier {
- @Override
- public final AbstractConfigValue modifyChildMayThrow(String keyOrNull, AbstractConfigValue v)
- throws Exception {
- try {
- return modifyChild(keyOrNull, v);
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- throw new BugOrBroken("Unexpected exception", e);
- }
- }
-
- abstract AbstractConfigValue modifyChild(String keyOrNull, AbstractConfigValue v);
- }
-
- @Override
- public AbstractConfigValue toFallbackValue() {
- return this;
- }
-
- protected abstract AbstractConfigValue newCopy(ConfigOrigin origin);
-
- // this is virtualized rather than a field because only some subclasses
- // really need to store the boolean, and they may be able to pack it
- // with another boolean to save space.
- protected boolean ignoresFallbacks() {
- // if we are not resolved, then somewhere in this value there's
- // a substitution that may need to look at the fallbacks.
- return resolveStatus() == ResolveStatus.RESOLVED;
- }
-
- protected AbstractConfigValue withFallbacksIgnored() {
- if (ignoresFallbacks()) {
- return this;
- }
- throw new BugOrBroken(
- "value class doesn't implement forced fallback-ignoring " + this);
- }
-
- // the withFallback() implementation is supposed to avoid calling
- // mergedWith* if we're ignoring fallbacks.
- protected final void requireNotIgnoringFallbacks() {
- if (ignoresFallbacks()) {
- throw new BugOrBroken(
- "method should not have been called with ignoresFallbacks=true " + getClass().getSimpleName());
- }
- }
-
- protected AbstractConfigValue constructDelayedMerge(ConfigOrigin origin,
- List<AbstractConfigValue> stack) {
- return new ConfigDelayedMerge(origin, stack);
- }
-
- protected final AbstractConfigValue mergedWithTheUnmergeable(
- Collection<AbstractConfigValue> stack, Unmergeable fallback) {
- requireNotIgnoringFallbacks();
-
- // if we turn out to be an object, and the fallback also does,
- // then a merge may be required; delay until we resolve.
- List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>();
- newStack.addAll(stack);
- newStack.addAll(fallback.unmergedValues());
- return constructDelayedMerge(AbstractConfigObject.mergeOrigins(newStack), newStack);
- }
-
- private final AbstractConfigValue delayMerge(Collection<AbstractConfigValue> stack,
- AbstractConfigValue fallback) {
- // if we turn out to be an object, and the fallback also does,
- // then a merge may be required.
- // if we contain a substitution, resolving it may need to look
- // back to the fallback.
- List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>();
- newStack.addAll(stack);
- newStack.add(fallback);
- return constructDelayedMerge(AbstractConfigObject.mergeOrigins(newStack), newStack);
- }
-
- protected final AbstractConfigValue mergedWithObject(Collection<AbstractConfigValue> stack,
- AbstractConfigObject fallback) {
- requireNotIgnoringFallbacks();
-
- if (this instanceof AbstractConfigObject) {
- throw new BugOrBroken("Objects must reimplement mergedWithObject");
- }
-
- return mergedWithNonObject(stack, fallback);
- }
-
- protected final AbstractConfigValue mergedWithNonObject(Collection<AbstractConfigValue> stack,
- AbstractConfigValue fallback) {
- requireNotIgnoringFallbacks();
-
- if (resolveStatus() == ResolveStatus.RESOLVED) {
- // falling back to a non-object doesn't merge anything, and also
- // prohibits merging any objects that we fall back to later.
- // so we have to switch to ignoresFallbacks mode.
- return withFallbacksIgnored();
- }
- // if unresolved, we may have to look back to fallbacks as part of
- // the resolution process, so always delay
- return delayMerge(stack, fallback);
- }
-
- protected AbstractConfigValue mergedWithTheUnmergeable(Unmergeable fallback) {
- requireNotIgnoringFallbacks();
-
- return mergedWithTheUnmergeable(Collections.singletonList(this), fallback);
- }
-
- protected AbstractConfigValue mergedWithObject(AbstractConfigObject fallback) {
- requireNotIgnoringFallbacks();
-
- return mergedWithObject(Collections.singletonList(this), fallback);
- }
-
- protected AbstractConfigValue mergedWithNonObject(AbstractConfigValue fallback) {
- requireNotIgnoringFallbacks();
-
- return mergedWithNonObject(Collections.singletonList(this), fallback);
- }
-
- @Override
- public AbstractConfigValue withOrigin(ConfigOrigin origin) {
- if (this.origin == origin) {
- return this;
- }
- return newCopy(origin);
- }
-
- // this is only overridden to change the return type
- @Override
- public AbstractConfigValue withFallback(ConfigMergeable mergeable) {
- if (ignoresFallbacks()) {
- return this;
- }
- ConfigValue other = ((MergeableValue) mergeable).toFallbackValue();
- if (other instanceof Unmergeable) {
- return mergedWithTheUnmergeable((Unmergeable) other);
- } else if (other instanceof AbstractConfigObject) {
- return mergedWithObject((AbstractConfigObject) other);
- }
- return mergedWithNonObject((AbstractConfigValue) other);
- }
-
- protected boolean canEqual(Object other) {
- return other instanceof ConfigValue;
- }
-
- @Override
- public boolean equals(Object other) {
- // note that "origin" is deliberately NOT part of equality
- if (other instanceof ConfigValue) {
- return canEqual(other)
- && (this.valueType() ==
- ((ConfigValue) other).valueType())
- && ConfigImplUtil.equalsHandlingNull(this.unwrapped(),
- ((ConfigValue) other).unwrapped());
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- // note that "origin" is deliberately NOT part of equality
- Object o = this.unwrapped();
- if (o == null) {
- return 0;
- }
- return o.hashCode();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- render(sb, 0, true /* atRoot */, null /* atKey */, ConfigRenderOptions.concise());
- return getClass().getSimpleName() + "(" + sb.toString() + ")";
- }
-
- protected static void indent(StringBuilder sb, int indent, ConfigRenderOptions options) {
- if (options.getFormatted()) {
- int remaining = indent;
- while (remaining > 0) {
- sb.append(" ");
- --remaining;
- }
- }
- }
-
- protected void render(StringBuilder sb, int indent, boolean atRoot, String atKey, ConfigRenderOptions options) {
- if (atKey != null) {
- String renderedKey;
- if (options.getJson()) {
- renderedKey = ConfigImplUtil.renderJsonString(atKey);
- } else {
- renderedKey = ConfigImplUtil.renderStringUnquotedIfPossible(atKey);
- }
-
- sb.append(renderedKey);
-
- if (options.getJson()) {
- if (options.getFormatted()) {
- sb.append(" : ");
- } else {
- sb.append(":");
- }
- } else {
- // in non-JSON we can omit the colon or equals before an object
- if (this instanceof ConfigObject) {
- if (options.getFormatted()) {
- sb.append(' ');
- }
- } else {
- sb.append("=");
- }
- }
- }
- render(sb, indent, atRoot, options);
- }
-
- protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
- Object u = unwrapped();
- sb.append(u.toString());
- }
-
- @Override
- public final String render() {
- return render(ConfigRenderOptions.defaults());
- }
-
- @Override
- public final String render(ConfigRenderOptions options) {
- StringBuilder sb = new StringBuilder();
- render(sb, 0, true, null, options);
- return sb.toString();
- }
-
- // toString() is a debugging-oriented string but this is defined
- // to create a string that would parse back to the value in JSON.
- // It only works for primitive values (that would be a single token)
- // which are auto-converted to strings when concatenating with
- // other strings or by the DefaultTransformer.
- String transformToString() {
- return null;
- }
-
- SimpleConfig atKey(ConfigOrigin origin, String key) {
- Map<String, AbstractConfigValue> m = Collections.singletonMap(key, this);
- return (new SimpleConfigObject(origin, m)).toConfig();
- }
-
- @Override
- public SimpleConfig atKey(String key) {
- return atKey(SimpleConfigOrigin.newSimple("atKey(" + key + ")"), key);
- }
-
- SimpleConfig atPath(ConfigOrigin origin, Path path) {
- Path parent = path.parent();
- SimpleConfig result = atKey(origin, path.last());
- while (parent != null) {
- String key = parent.last();
- result = result.atKey(origin, key);
- parent = parent.parent();
- }
- return result;
- }
-
- @Override
- public SimpleConfig atPath(String pathExpression) {
- SimpleConfigOrigin origin = SimpleConfigOrigin.newSimple("atPath(" + pathExpression + ")");
- return atPath(origin, Path.newPath(pathExpression));
- }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigBeanImpl.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigBeanImpl.java
deleted file mode 100644
index 1cb7be7..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigBeanImpl.java
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.Config;
-import org.apache.seatunnel.config.ConfigException.BadBean;
-import org.apache.seatunnel.config.ConfigException.Missing;
-import org.apache.seatunnel.config.ConfigException.NotResolved;
-import org.apache.seatunnel.config.ConfigException.ValidationFailed;
-import org.apache.seatunnel.config.ConfigException.ValidationProblem;
-import org.apache.seatunnel.config.ConfigList;
-import org.apache.seatunnel.config.ConfigMemorySize;
-import org.apache.seatunnel.config.ConfigObject;
-import org.apache.seatunnel.config.ConfigValue;
-import org.apache.seatunnel.config.ConfigValueType;
-import org.apache.seatunnel.config.Optional;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Internal implementation detail, not ABI stable, do not touch.
- * For use only by the {@link org.apache.seatunnel.config} package.
- */
-public class ConfigBeanImpl {
-
- /**
- * This is public ONLY for use by the "config" package, DO NOT USE this ABI
- * may change.
- *
- * @param <T> type of the bean
- * @param config config to use
- * @param clazz class of the bean
- * @return the bean instance
- */
- public static <T> T createInternal(Config config, Class<T> clazz) {
- if (((SimpleConfig) config).root().resolveStatus() != ResolveStatus.RESOLVED) {
- throw new NotResolved(
- "need to Config#resolve() a config before using it to initialize a bean, see the API docs for Config#resolve()");
- }
-
- Map<String, AbstractConfigValue> configProps = new HashMap<String, AbstractConfigValue>();
- Map<String, String> originalNames = new HashMap<String, String>();
- for (Map.Entry<String, ConfigValue> configProp : config.root().entrySet()) {
- String originalName = configProp.getKey();
- String camelName = ConfigImplUtil.toCamelCase(originalName);
- // if a setting is in there both as some hyphen name and the camel name,
- // the camel one wins
- if (originalNames.containsKey(camelName) && !originalName.equals(camelName)) {
- // if we aren't a camel name to start with, we lose.
- // if we are or we are the first matching key, we win.
- } else {
- configProps.put(camelName, (AbstractConfigValue) configProp.getValue());
- originalNames.put(camelName, originalName);
- }
- }
-
- BeanInfo beanInfo = null;
- try {
- beanInfo = Introspector.getBeanInfo(clazz);
- } catch (IntrospectionException e) {
- throw new BadBean("Could not get bean information for class " + clazz.getName(), e);
- }
-
- try {
- List<PropertyDescriptor> beanProps = new ArrayList<PropertyDescriptor>();
- for (PropertyDescriptor beanProp : beanInfo.getPropertyDescriptors()) {
- if (beanProp.getReadMethod() == null || beanProp.getWriteMethod() == null) {
- continue;
- }
- beanProps.add(beanProp);
- }
-
- // Try to throw all validation issues at once (this does not comprehensively
- // find every issue, but it should find common ones).
- List<ValidationProblem> problems = new ArrayList<ValidationProblem>();
- for (PropertyDescriptor beanProp : beanProps) {
- Method setter = beanProp.getWriteMethod();
- Class<?> parameterClass = setter.getParameterTypes()[0];
-
- ConfigValueType expectedType = getValueTypeOrNull(parameterClass);
- if (expectedType != null) {
- String name = originalNames.get(beanProp.getName());
- if (name == null) {
- name = beanProp.getName();
- }
- Path path = Path.newKey(name);
- AbstractConfigValue configValue = configProps.get(beanProp.getName());
- if (configValue != null) {
- SimpleConfig.checkValid(path, expectedType, configValue, problems);
- } else {
- if (!isOptionalProperty(clazz, beanProp)) {
- SimpleConfig.addMissing(problems, expectedType, path, config.origin());
- }
- }
- }
- }
-
- if (!problems.isEmpty()) {
- throw new ValidationFailed(problems);
- }
-
- // Fill in the bean instance
- T bean = clazz.newInstance();
- for (PropertyDescriptor beanProp : beanProps) {
- Method setter = beanProp.getWriteMethod();
- Type parameterType = setter.getGenericParameterTypes()[0];
- Class<?> parameterClass = setter.getParameterTypes()[0];
- String configPropName = originalNames.get(beanProp.getName());
- // Is the property key missing in the config?
- if (configPropName == null) {
- // If so, continue if the field is marked as @{link Optional}
- if (isOptionalProperty(clazz, beanProp)) {
- continue;
- }
- // Otherwise, raise a {@link Missing} exception right here
- throw new Missing(beanProp.getName());
- }
- Object unwrapped = getValue(clazz, parameterType, parameterClass, config, configPropName);
- setter.invoke(bean, unwrapped);
- }
- return bean;
- } catch (InstantiationException e) {
- throw new BadBean(clazz.getName()
- + " needs a public no-args constructor to be used as a bean", e);
- } catch (IllegalAccessException e) {
- throw new BadBean(clazz.getName()
- + " getters and setters are not accessible, they must be for use as a bean", e);
- } catch (InvocationTargetException e) {
- throw new BadBean("Calling bean method on "
- + clazz.getName() + " caused an exception", e);
- }
- }
-
- // we could magically make this work in many cases by doing
- // getAnyRef() (or getValue().unwrapped()), but anytime we
- // rely on that, we aren't doing the type conversions Config
- // usually does, and we will throw ClassCastException instead
- // of a nicer error message giving the name of the bad
- // setting. So, instead, we only support a limited number of
- // types plus you can always use Object, ConfigValue, Config,
- // ConfigObject, etc. as an escape hatch.
- private static Object getValue(Class<?> beanClass, Type parameterType, Class<?> parameterClass, Config config,
- String configPropName) {
- if (parameterClass == Boolean.class || parameterClass == boolean.class) {
- return config.getBoolean(configPropName);
- } else if (parameterClass == Integer.class || parameterClass == int.class) {
- return config.getInt(configPropName);
- } else if (parameterClass == Double.class || parameterClass == double.class) {
- return config.getDouble(configPropName);
- } else if (parameterClass == Long.class || parameterClass == long.class) {
- return config.getLong(configPropName);
- } else if (parameterClass == String.class) {
- return config.getString(configPropName);
- } else if (parameterClass == Duration.class) {
- return config.getDuration(configPropName);
- } else if (parameterClass == ConfigMemorySize.class) {
- return config.getMemorySize(configPropName);
- } else if (parameterClass == Object.class) {
- return config.getAnyRef(configPropName);
- } else if (parameterClass == List.class) {
- return getListValue(beanClass, parameterType, parameterClass, config, configPropName);
- } else if (parameterClass == Set.class) {
- return getSetValue(beanClass, parameterType, parameterClass, config, configPropName);
- } else if (parameterClass == Map.class) {
- // we could do better here, but right now we don't.
- Type[] typeArgs = ((ParameterizedType) parameterType).getActualTypeArguments();
- if (typeArgs[0] != String.class || typeArgs[1] != Object.class) {
- throw new BadBean("Bean property '"
- + configPropName + "' of class "
- + beanClass.getName()
- + " has unsupported Map<"
- + typeArgs[0] + "," + typeArgs[1]
- + ">, only Map<String,Object> is supported right now");
- }
- return config.getObject(configPropName).unwrapped();
- } else if (parameterClass == Config.class) {
- return config.getConfig(configPropName);
- } else if (parameterClass == ConfigObject.class) {
- return config.getObject(configPropName);
- } else if (parameterClass == ConfigValue.class) {
- return config.getValue(configPropName);
- } else if (parameterClass == ConfigList.class) {
- return config.getList(configPropName);
- } else if (parameterClass.isEnum()) {
- @SuppressWarnings("unchecked")
- Enum enumValue = config.getEnum((Class<Enum>) parameterClass, configPropName);
- return enumValue;
- } else if (hasAtLeastOneBeanProperty(parameterClass)) {
- return createInternal(config.getConfig(configPropName), parameterClass);
- }
- throw new BadBean("Bean property "
- + configPropName + " of class "
- + beanClass.getName()
- + " has unsupported type "
- + parameterType);
- }
-
- private static Object getSetValue(Class<?> beanClass, Type parameterType, Class<?> parameterClass, Config config, String configPropName) {
- return new HashSet((List) getListValue(beanClass, parameterType, parameterClass, config, configPropName));
- }
-
- private static Object getListValue(Class<?> beanClass, Type parameterType, Class<?> parameterClass, Config config, String configPropName) {
- Type elementType = ((ParameterizedType) parameterType).getActualTypeArguments()[0];
-
- if (elementType == Boolean.class) {
- return config.getBooleanList(configPropName);
- } else if (elementType == Integer.class) {
- return config.getIntList(configPropName);
- } else if (elementType == Double.class) {
- return config.getDoubleList(configPropName);
- } else if (elementType == Long.class) {
- return config.getLongList(configPropName);
- } else if (elementType == String.class) {
- return config.getStringList(configPropName);
- } else if (elementType == Duration.class) {
- return config.getDurationList(configPropName);
- } else if (elementType == ConfigMemorySize.class) {
- return config.getMemorySizeList(configPropName);
- } else if (elementType == Object.class) {
- return config.getAnyRefList(configPropName);
- } else if (elementType == Config.class) {
- return config.getConfigList(configPropName);
- } else if (elementType == ConfigObject.class) {
- return config.getObjectList(configPropName);
- } else if (elementType == ConfigValue.class) {
- return config.getList(configPropName);
- } else if (((Class<?>) elementType).isEnum()) {
- @SuppressWarnings("unchecked")
- List<Enum> enumValues = config.getEnumList((Class<Enum>) elementType, configPropName);
- return enumValues;
- } else if (hasAtLeastOneBeanProperty((Class<?>) elementType)) {
- List<Object> beanList = new ArrayList<Object>();
- List<? extends Config> configList = config.getConfigList(configPropName);
- for (Config listMember : configList) {
- beanList.add(createInternal(listMember, (Class<?>) elementType));
- }
- return beanList;
- }
- throw new BadBean("Bean property '"
- + configPropName + "' of class "
- + beanClass.getName()
- + " has unsupported list element type "
- + elementType);
- }
-
- // null if we can't easily say; this is heuristic/best-effort
- private static ConfigValueType getValueTypeOrNull(Class<?> parameterClass) {
- if (parameterClass == Boolean.class || parameterClass == boolean.class) {
- return ConfigValueType.BOOLEAN;
- } else if (parameterClass == Integer.class || parameterClass == int.class) {
- return ConfigValueType.NUMBER;
- } else if (parameterClass == Double.class || parameterClass == double.class) {
- return ConfigValueType.NUMBER;
- } else if (parameterClass == Long.class || parameterClass == long.class) {
- return ConfigValueType.NUMBER;
- } else if (parameterClass == String.class) {
- return ConfigValueType.STRING;
- } else if (parameterClass == Duration.class) {
- return null;
- } else if (parameterClass == ConfigMemorySize.class) {
- return null;
- } else if (parameterClass == List.class) {
- return ConfigValueType.LIST;
- } else if (parameterClass == Map.class) {
- return ConfigValueType.OBJECT;
- } else if (parameterClass == Config.class) {
- return ConfigValueType.OBJECT;
- } else if (parameterClass == ConfigObject.class) {
- return ConfigValueType.OBJECT;
- } else if (parameterClass == ConfigList.class) {
- return ConfigValueType.LIST;
- }
- return null;
- }
-
- private static boolean hasAtLeastOneBeanProperty(Class<?> clazz) {
- BeanInfo beanInfo = null;
- try {
- beanInfo = Introspector.getBeanInfo(clazz);
- } catch (IntrospectionException e) {
- return false;
- }
-
- for (PropertyDescriptor beanProp : beanInfo.getPropertyDescriptors()) {
- if (beanProp.getReadMethod() != null && beanProp.getWriteMethod() != null) {
- return true;
- }
- }
-
- return false;
- }
-
- private static boolean isOptionalProperty(Class beanClass, PropertyDescriptor beanProp) {
- Field field = getField(beanClass, beanProp.getName());
- return field != null && (field.getAnnotationsByType(Optional.class).length > 0);
- }
-
- private static Field getField(Class beanClass, String fieldName) {
- try {
- Field field = beanClass.getDeclaredField(fieldName);
- field.setAccessible(true);
- return field;
- } catch (NoSuchFieldException e) {
- // Don't give up yet. Try to look for field in super class, if any.
- }
- beanClass = beanClass.getSuperclass();
- if (beanClass == null) {
- return null;
- }
- return getField(beanClass, fieldName);
- }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigBoolean.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigBoolean.java
deleted file mode 100644
index 9d4cd30..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigBoolean.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigValueType;
-
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-
-final class ConfigBoolean extends AbstractConfigValue implements Serializable {
-
- private static final long serialVersionUID = 2L;
-
- private final boolean value;
-
- ConfigBoolean(ConfigOrigin origin, boolean value) {
- super(origin);
- this.value = value;
- }
-
- @Override
- public ConfigValueType valueType() {
- return ConfigValueType.BOOLEAN;
- }
-
- @Override
- public Boolean unwrapped() {
- return value;
- }
-
- @Override
- String transformToString() {
- return value ? "true" : "false";
- }
-
- @Override
- protected ConfigBoolean newCopy(ConfigOrigin origin) {
- return new ConfigBoolean(origin, value);
- }
-
- // serialization all goes through SerializedConfigValue
- private Object writeReplace() throws ObjectStreamException {
- return new SerializedConfigValue(this);
- }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigConcatenation.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigConcatenation.java
deleted file mode 100644
index c12306d..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigConcatenation.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.ConfigException.BugOrBroken;
-import org.apache.seatunnel.config.ConfigException.NotResolved;
-import org.apache.seatunnel.config.ConfigException.WrongType;
-import org.apache.seatunnel.config.ConfigObject;
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigRenderOptions;
-import org.apache.seatunnel.config.ConfigValueType;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A ConfigConcatenation represents a list of values to be concatenated (see the
- * spec). It only has to exist if at least one value is an unresolved
- * substitution, otherwise we could go ahead and collapse the list into a single
- * value.
- * <p>
- * Right now this is always a list of strings and ${} references, but in the
- * future should support a list of ConfigList. We may also support
- * concatenations of objects, but ConfigDelayedMerge should be used for that
- * since a concat of objects really will merge, not concatenate.
- */
-final class ConfigConcatenation extends AbstractConfigValue implements Unmergeable, Container {
-
- private final List<AbstractConfigValue> pieces;
-
- ConfigConcatenation(ConfigOrigin origin, List<AbstractConfigValue> pieces) {
- super(origin);
- this.pieces = pieces;
-
- if (pieces.size() < 2) {
- throw new BugOrBroken("Created concatenation with less than 2 items: " + this);
- }
-
- boolean hadUnmergeable = false;
- for (AbstractConfigValue p : pieces) {
- if (p instanceof ConfigConcatenation) {
- throw new BugOrBroken(
- "ConfigConcatenation should never be nested: " + this);
- }
- if (p instanceof Unmergeable) {
- hadUnmergeable = true;
- }
- }
- if (!hadUnmergeable) {
- throw new BugOrBroken(
- "Created concatenation without an unmergeable in it: " + this);
- }
- }
-
- private NotResolved notResolved() {
- return new NotResolved(
- "need to Config#resolve(), see the API docs for Config#resolve(); substitution not resolved: " + this);
- }
-
- @Override
- public ConfigValueType valueType() {
- throw notResolved();
- }
-
- @Override
- public Object unwrapped() {
- throw notResolved();
- }
-
- @Override
- protected ConfigConcatenation newCopy(ConfigOrigin newOrigin) {
- return new ConfigConcatenation(newOrigin, pieces);
- }
-
- @Override
- protected boolean ignoresFallbacks() {
- // we can never ignore fallbacks because if a child ConfigReference
- // is self-referential we have to look lower in the merge stack
- // for its value.
- return false;
- }
-
- @Override
- public Collection<ConfigConcatenation> unmergedValues() {
- return Collections.singleton(this);
- }
-
- private static boolean isIgnoredWhitespace(AbstractConfigValue value) {
- return (value instanceof ConfigString) && !((ConfigString) value).wasQuoted();
- }
-
- /**
- * Add left and right, or their merger, to builder.
- */
- private static void join(ArrayList<AbstractConfigValue> builder, AbstractConfigValue origRight) {
- AbstractConfigValue left = builder.get(builder.size() - 1);
- AbstractConfigValue right = origRight;
-
- // check for an object which can be converted to a list
- // (this will be an object with numeric keys, like foo.0, foo.1)
- if (left instanceof ConfigObject && right instanceof SimpleConfigList) {
- left = DefaultTransformer.transform(left, ConfigValueType.LIST);
- } else if (left instanceof SimpleConfigList && right instanceof ConfigObject) {
- right = DefaultTransformer.transform(right, ConfigValueType.LIST);
- }
-
- // Since this depends on the type of two instances, I couldn't think
- // of much alternative to an instanceof chain. Visitors are sometimes
- // used for multiple dispatch but seems like overkill.
- AbstractConfigValue joined = null;
- if (left instanceof ConfigObject && right instanceof ConfigObject) {
- joined = right.withFallback(left);
- } else if (left instanceof SimpleConfigList && right instanceof SimpleConfigList) {
- joined = ((SimpleConfigList) left).concatenate((SimpleConfigList) right);
- } else if ((left instanceof SimpleConfigList || left instanceof ConfigObject) &&
- isIgnoredWhitespace(right)) {
- joined = left;
- // it should be impossible that left is whitespace and right is a list or object
- } else if (left instanceof ConfigConcatenation || right instanceof ConfigConcatenation) {
- throw new BugOrBroken("unflattened ConfigConcatenation");
- } else if (left instanceof Unmergeable || right instanceof Unmergeable) {
- // leave joined=null, cannot join
- } else {
- // handle primitive type or primitive type mixed with object or list
- String s1 = left.transformToString();
- String s2 = right.transformToString();
- if (s1 == null || s2 == null) {
- throw new WrongType(left.origin(),
- "Cannot concatenate object or list with a non-object-or-list, " + left + " and " + right + " are not compatible");
- } else {
- ConfigOrigin joinedOrigin = SimpleConfigOrigin.mergeOrigins(left.origin(),
- right.origin());
- joined = new ConfigString.Quoted(joinedOrigin, s1 + s2);
- }
- }
-
- if (joined == null) {
- builder.add(right);
- } else {
- builder.remove(builder.size() - 1);
- builder.add(joined);
- }
- }
-
- static List<AbstractConfigValue> consolidate(List<AbstractConfigValue> pieces) {
- if (pieces.size() < 2) {
- return pieces;
- }
- List<AbstractConfigValue> flattened = new ArrayList<AbstractConfigValue>(pieces.size());
- for (AbstractConfigValue v : pieces) {
- if (v instanceof ConfigConcatenation) {
- flattened.addAll(((ConfigConcatenation) v).pieces);
- } else {
- flattened.add(v);
- }
- }
-
- ArrayList<AbstractConfigValue> consolidated = new ArrayList<AbstractConfigValue>(
- flattened.size());
- for (AbstractConfigValue v : flattened) {
- if (consolidated.isEmpty()) {
- consolidated.add(v);
- } else {
- join(consolidated, v);
- }
- }
-
- return consolidated;
- }
-
- static AbstractConfigValue concatenate(List<AbstractConfigValue> pieces) {
- List<AbstractConfigValue> consolidated = consolidate(pieces);
- if (consolidated.isEmpty()) {
- return null;
- } else if (consolidated.size() == 1) {
- return consolidated.get(0);
- }
- ConfigOrigin mergedOrigin = SimpleConfigOrigin.mergeOrigins(consolidated);
- return new ConfigConcatenation(mergedOrigin, consolidated);
- }
-
- @Override
- ResolveResult<? extends AbstractConfigValue> resolveSubstitutions(ResolveContext context, ResolveSource source)
- throws NotPossibleToResolve {
- if (ConfigImpl.traceSubSituationsEnable()) {
- int indent = context.depth() + 2;
- ConfigImpl.trace(indent - 1, "concatenation has " + pieces.size() + " pieces:");
- int count = 0;
- for (AbstractConfigValue v : pieces) {
- ConfigImpl.trace(indent, count + ": " + v);
- count += 1;
- }
- }
-
- // Right now there's no reason to pushParent here because the
- // content of ConfigConcatenation should not need to replaceChild,
- // but if it did we'd have to do this.
- ResolveSource sourceWithParent = source; // .pushParent(this);
- ResolveContext newContext = context;
-
- List<AbstractConfigValue> resolved = new ArrayList<AbstractConfigValue>(pieces.size());
- for (AbstractConfigValue p : pieces) {
- // to concat into a string we have to do a full resolve,
- // so unrestrict the context, then put restriction back afterward
- Path restriction = newContext.restrictToChild();
- ResolveResult<? extends AbstractConfigValue> result = newContext.unrestricted()
- .resolve(p, sourceWithParent);
- AbstractConfigValue r = result.value;
- newContext = result.context.restrict(restriction);
- if (ConfigImpl.traceSubSituationsEnable()) {
- ConfigImpl.trace(context.depth(), "resolved concat piece to " + r);
- }
- if (r == null) {
- // it was optional... omit
- } else {
- resolved.add(r);
- }
- }
-
- // now need to concat everything
- List<AbstractConfigValue> joined = consolidate(resolved);
- // if unresolved is allowed we can just become another
- // ConfigConcatenation
- if (joined.size() > 1 && context.options().getAllowUnresolved()) {
- return ResolveResult.make(newContext, new ConfigConcatenation(this.origin(), joined));
- } else if (joined.isEmpty()) {
- // we had just a list of optional references using ${?}
- return ResolveResult.make(newContext, null);
- } else if (joined.size() == 1) {
- return ResolveResult.make(newContext, joined.get(0));
- }
- throw new BugOrBroken("Bug in the library; resolved list was joined to too many values: " + joined);
- }
-
- @Override
- ResolveStatus resolveStatus() {
- return ResolveStatus.UNRESOLVED;
- }
-
- @Override
- public ConfigConcatenation replaceChild(AbstractConfigValue child, AbstractConfigValue replacement) {
- List<AbstractConfigValue> newPieces = replaceChildInList(pieces, child, replacement);
- if (newPieces == null) {
- return null;
- }
- return new ConfigConcatenation(origin(), newPieces);
- }
-
- @Override
- public boolean hasDescendant(AbstractConfigValue descendant) {
- return hasDescendantInList(pieces, descendant);
- }
-
- // when you graft a substitution into another object,
- // you have to prefix it with the location in that object
- // where you grafted it; but save prefixLength so
- // system property and env variable lookups don't get
- // broken.
- @Override
- ConfigConcatenation relativized(Path prefix) {
- List<AbstractConfigValue> newPieces = new ArrayList<AbstractConfigValue>();
- for (AbstractConfigValue p : pieces) {
- newPieces.add(p.relativized(prefix));
- }
- return new ConfigConcatenation(origin(), newPieces);
- }
-
- @Override
- protected boolean canEqual(Object other) {
- return other instanceof ConfigConcatenation;
- }
-
- @Override
- public boolean equals(Object other) {
- // note that "origin" is deliberately NOT part of equality
- if (other instanceof ConfigConcatenation) {
- return canEqual(other) && this.pieces.equals(((ConfigConcatenation) other).pieces);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- // note that "origin" is deliberately NOT part of equality
- return pieces.hashCode();
- }
-
- @Override
- protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
- for (AbstractConfigValue p : pieces) {
- p.render(sb, indent, atRoot, options);
- }
- }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigDelayedMerge.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigDelayedMerge.java
deleted file mode 100644
index 8398c55..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigDelayedMerge.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.ConfigException.BugOrBroken;
-import org.apache.seatunnel.config.ConfigException.NotResolved;
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigRenderOptions;
-import org.apache.seatunnel.config.ConfigValueType;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * The issue here is that we want to first merge our stack of config files, and
- * then we want to evaluate substitutions. But if two substitutions both expand
- * to an object, we might need to merge those two objects. Thus, we can't ever
- * "override" a substitution when we do a merge; instead we have to save the
- * stack of values that should be merged, and resolve the merge when we evaluate
- * substitutions.
- */
-final class ConfigDelayedMerge extends AbstractConfigValue implements Unmergeable,
- ReplaceableMergeStack {
-
- // earlier items in the stack win
- private final List<AbstractConfigValue> stack;
-
- ConfigDelayedMerge(ConfigOrigin origin, List<AbstractConfigValue> stack) {
- super(origin);
- this.stack = stack;
- if (stack.isEmpty()) {
- throw new BugOrBroken(
- "creating empty delayed merge value");
- }
-
- for (AbstractConfigValue v : stack) {
- if (v instanceof ConfigDelayedMerge || v instanceof ConfigDelayedMergeObject) {
- throw new BugOrBroken(
- "placed nested DelayedMerge in a ConfigDelayedMerge, should have consolidated stack");
- }
- }
- }
-
- @Override
- public ConfigValueType valueType() {
- throw new NotResolved(
- "called valueType() on value with unresolved substitutions, need to Config#resolve() first, see API docs");
- }
-
- @Override
- public Object unwrapped() {
- throw new NotResolved(
- "called unwrapped() on value with unresolved substitutions, need to Config#resolve() first, see API docs");
- }
-
- @Override
- ResolveResult<? extends AbstractConfigValue> resolveSubstitutions(ResolveContext context, ResolveSource source)
- throws NotPossibleToResolve {
- return resolveSubstitutions(this, stack, context, source);
- }
-
- // static method also used by ConfigDelayedMergeObject
- static ResolveResult<? extends AbstractConfigValue> resolveSubstitutions(ReplaceableMergeStack replaceable,
- List<AbstractConfigValue> stack,
- ResolveContext context, ResolveSource source) throws NotPossibleToResolve {
- if (ConfigImpl.traceSubSituationsEnable()) {
- ConfigImpl.trace(context.depth(), "delayed merge stack has " + stack.size() + " items:");
- int count = 0;
- for (AbstractConfigValue v : stack) {
- ConfigImpl.trace(context.depth() + 1, count + ": " + v);
- count += 1;
- }
- }
-
- // to resolve substitutions, we need to recursively resolve
- // the stack of stuff to merge, and merge the stack so
- // we won't be a delayed merge anymore. If restrictToChildOrNull
- // is non-null, or resolve options allow partial resolves,
- // we may remain a delayed merge though.
-
- ResolveContext newContext = context;
- int count = 0;
- AbstractConfigValue merged = null;
- for (AbstractConfigValue end : stack) {
- // the end value may or may not be resolved already
-
- ResolveSource sourceForEnd;
-
- if (end instanceof ReplaceableMergeStack) {
- throw new BugOrBroken("A delayed merge should not contain another one: " + replaceable);
- } else if (end instanceof Unmergeable) {
- // the remainder could be any kind of value, including another
- // ConfigDelayedMerge
- AbstractConfigValue remainder = replaceable.makeReplacement(context, count + 1);
-
- if (ConfigImpl.traceSubSituationsEnable()) {
- ConfigImpl.trace(newContext.depth(), "remainder portion: " + remainder);
- }
-
- // If, while resolving 'end' we come back to the same
- // merge stack, we only want to look _below_ 'end'
- // in the stack. So we arrange to replace the
- // ConfigDelayedMerge with a value that is only
- // the remainder of the stack below this one.
-
- if (ConfigImpl.traceSubSituationsEnable()) {
- ConfigImpl.trace(newContext.depth(), "building sourceForEnd");
- }
-
- // we resetParents() here because we'll be resolving "end"
- // against a root which does NOT contain "end"
- sourceForEnd = source.replaceWithinCurrentParent((AbstractConfigValue) replaceable, remainder);
-
- if (ConfigImpl.traceSubSituationsEnable()) {
- ConfigImpl.trace(newContext.depth(), " sourceForEnd before reset parents but after replace: " + sourceForEnd);
- }
-
- sourceForEnd = sourceForEnd.resetParents();
- } else {
- if (ConfigImpl.traceSubSituationsEnable()) {
- ConfigImpl.trace(newContext.depth(),
- "will resolve end against the original source with parent pushed");
- }
-
- sourceForEnd = source.pushParent(replaceable);
- }
-
- if (ConfigImpl.traceSubSituationsEnable()) {
- ConfigImpl.trace(newContext.depth(), "sourceForEnd =" + sourceForEnd);
- }
-
- if (ConfigImpl.traceSubSituationsEnable()) {
- ConfigImpl.trace(newContext.depth(), "Resolving highest-priority item in delayed merge "
- + end + " against " + sourceForEnd
- + " endWasRemoved=" + (source != sourceForEnd));
- }
- ResolveResult<? extends AbstractConfigValue> result = newContext.resolve(end, sourceForEnd);
- AbstractConfigValue resolvedEnd = result.value;
- newContext = result.context;
-
... 16846 lines suppressed ...