This is an automated email from the ASF dual-hosted git repository. gaojun2048 pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/seatunnel-web.git
The following commit(s) were added to refs/heads/main by this push:
new 627655d9 [Hotfix] Fix dynamic form item show by other item bug (#131)
627655d9 is described below
commit 627655d9025831425891c31b73949b9783baba35
Author: Eric <[email protected]>
AuthorDate: Wed Oct 18 11:01:20 2023 +0800
[Hotfix] Fix dynamic form item show by other item bug (#131)
* Fix dynamic form item show by other item bug
---
.../framework/SeaTunnelOptionRuleWrapper.java | 321 +++++++++++----------
.../app/dynamicforms/AbstractFormOption.java | 5 +-
.../app/dynamicforms/FormStructureValidate.java | 26 ++
3 files changed, 194 insertions(+), 158 deletions(-)
diff --git
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/thirdparty/framework/SeaTunnelOptionRuleWrapper.java
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/thirdparty/framework/SeaTunnelOptionRuleWrapper.java
index 7a0bfb6e..4f5e7c60 100644
---
a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/thirdparty/framework/SeaTunnelOptionRuleWrapper.java
+++
b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/thirdparty/framework/SeaTunnelOptionRuleWrapper.java
@@ -22,6 +22,7 @@ import org.apache.seatunnel.api.configuration.util.Expression;
import org.apache.seatunnel.api.configuration.util.OptionRule;
import org.apache.seatunnel.api.configuration.util.RequiredOption;
import org.apache.seatunnel.app.dynamicforms.AbstractFormOption;
+import org.apache.seatunnel.app.dynamicforms.Constants;
import org.apache.seatunnel.app.dynamicforms.FormLocale;
import org.apache.seatunnel.app.dynamicforms.FormOptionBuilder;
import org.apache.seatunnel.app.dynamicforms.FormStructure;
@@ -40,6 +41,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
import java.util.stream.Collectors;
import static
org.apache.seatunnel.app.common.SeaTunnelConnectorI18n.CONNECTOR_I18N_CONFIG_EN;
@@ -74,20 +77,14 @@ public class SeaTunnelOptionRuleWrapper {
@NonNull String name) {
FormLocale locale = new FormLocale();
List<AbstractFormOption> optionFormOptions =
wrapperOptionOptions(name, optionList, locale);
- List<List<AbstractFormOption>> requiredFormOptions =
+ List<AbstractFormOption> requiredFormOptions =
wrapperRequiredOptions(name, requiredList, locale);
FormStructureBuilder formStructureBuilder =
FormStructure.builder().name(name);
if (!CollectionUtils.isEmpty(requiredFormOptions)) {
- requiredFormOptions.forEach(
- list -> {
- if (CollectionUtils.isEmpty(list)) {
- return;
- }
-
- formStructureBuilder.addFormOption(list.toArray(new
AbstractFormOption[1]));
- });
+ formStructureBuilder.addFormOption(
+ requiredFormOptions.toArray(new AbstractFormOption[1]));
}
if (!CollectionUtils.isEmpty(optionFormOptions)) {
@@ -110,167 +107,177 @@ public class SeaTunnelOptionRuleWrapper {
.collect(Collectors.toList());
}
- private static List<List<AbstractFormOption>> wrapperRequiredOptions(
+ private static List<AbstractFormOption> wrapperRequiredOptions(
@NonNull String connectorName,
@NonNull List<RequiredOption> requiredList,
FormLocale locale) {
- List<List<AbstractFormOption>> formOptionsList =
- requiredList.stream()
- .map(
+ List<AbstractFormOption> result = new ArrayList<>();
+ requiredList.forEach(
+ requiredOptions -> {
+ if (requiredOptions instanceof
RequiredOption.AbsolutelyRequiredOptions) {
+ RequiredOption.AbsolutelyRequiredOptions
absolutelyRequiredOptions =
+ (RequiredOption.AbsolutelyRequiredOptions)
requiredOptions;
+ absolutelyRequiredOptions
+ .getRequiredOption()
+ .forEach(
+ option -> {
+ AbstractFormOption
requiredFormItem = null;
+ for (AbstractFormOption formItem :
result) {
+ if
(formItem.getField().equals(option.key())) {
+ requiredFormItem =
formItem;
+ break;
+ }
+ }
+
+ if (requiredFormItem == null) {
+ requiredFormItem =
+ wrapperToFormOption(
+ connectorName,
option, locale);
+ result.add(requiredFormItem);
+ }
+
+ if (requiredFormItem.getValidate()
== null) {
+ requiredFormItem.withValidate(
+
ValidateBuilder.builder()
+
.nonEmptyValidateBuilder()
+
.nonEmptyValidate());
+ }
+ });
+ } else if (requiredOptions instanceof
RequiredOption.BundledRequiredOptions) {
+ List<Option<?>> bundledRequiredOptions =
+ ((RequiredOption.BundledRequiredOptions)
requiredOptions)
+ .getRequiredOption();
+ List<String> bundledFields =
+ bundledRequiredOptions.stream()
+ .map(requiredOption ->
requiredOption.key())
+ .collect(Collectors.toList());
+
+ bundledRequiredOptions.forEach(
option -> {
- if (option
- instanceof
RequiredOption.AbsolutelyRequiredOptions) {
- List<AbstractFormOption> collect =
-
((RequiredOption.AbsolutelyRequiredOptions) option)
-
.getRequiredOption().stream()
- .map(
-
requiredOption -> {
-
return wrapperToFormOption(
-
connectorName,
-
requiredOption,
-
locale)
-
.withValidate(
-
ValidateBuilder
-
.builder()
-
.nonEmptyValidateBuilder()
-
.nonEmptyValidate());
- })
-
.collect(Collectors.toList());
- return collect;
+ AbstractFormOption
bundledRequiredFormOption = null;
+ for (AbstractFormOption formItem : result)
{
+ if
(formItem.getField().equals(option.key())) {
+ bundledRequiredFormOption =
formItem;
+ break;
+ }
}
- if (option instanceof
RequiredOption.BundledRequiredOptions) {
- List<Option<?>> bundledRequiredOptions
=
-
((RequiredOption.BundledRequiredOptions) option)
- .getRequiredOption();
- List<String> bundledFields =
- bundledRequiredOptions.stream()
- .map(requiredOption ->
requiredOption.key())
-
.collect(Collectors.toList());
-
- List<AbstractFormOption> collect =
- bundledRequiredOptions.stream()
- .map(
- requiredOption
-> {
-
AbstractFormOption
-
bundledRequiredFormOption =
-
wrapperToFormOption(
-
connectorName,
-
requiredOption,
-
locale);
-
bundledRequiredFormOption
-
.withValidate(
-
ValidateBuilder
-
.builder()
-
.unionNonEmptyValidateBuilder()
-
.fields(
-
bundledFields
-
.toArray(
-
new String
-
[1]))
-
.unionNonEmptyValidate());
- return
bundledRequiredFormOption;
- })
-
.collect(Collectors.toList());
- return collect;
+ if (bundledRequiredFormOption == null) {
+ bundledRequiredFormOption =
+
wrapperToFormOption(connectorName, option, locale);
+ result.add(bundledRequiredFormOption);
}
- if (option instanceof
RequiredOption.ExclusiveRequiredOptions) {
- List<Option<?>> exclusiveOptions =
-
((RequiredOption.ExclusiveRequiredOptions) option)
- .getExclusiveOptions();
- List<String> exclusiveFields =
- exclusiveOptions.stream()
- .map(requiredOption ->
requiredOption.key())
-
.collect(Collectors.toList());
-
- List<AbstractFormOption> collect =
- exclusiveOptions.stream()
- .map(
- requiredOption
-> {
-
AbstractFormOption
-
exclusiveRequiredFormOption =
-
wrapperToFormOption(
-
connectorName,
-
requiredOption,
-
locale)
-
.withValidate(
-
ValidateBuilder
-
.builder()
-
.mutuallyExclusiveValidateBuilder()
-
.fields(
-
exclusiveFields
-
.toArray(
-
new String
-
[1]))
-
.mutuallyExclusiveValidate());
- return
exclusiveRequiredFormOption;
- })
-
.collect(Collectors.toList());
- return collect;
+ bundledRequiredFormOption.withValidate(
+ ValidateBuilder.builder()
+
.unionNonEmptyValidateBuilder()
+
.fields(bundledFields.toArray(new String[1]))
+ .unionNonEmptyValidate());
+ });
+ } else if (requiredOptions instanceof
RequiredOption.ExclusiveRequiredOptions) {
+ List<Option<?>> exclusiveOptions =
+ ((RequiredOption.ExclusiveRequiredOptions)
requiredOptions)
+ .getExclusiveOptions();
+ List<String> exclusiveFields =
+ exclusiveOptions.stream()
+ .map(requiredOption ->
requiredOption.key())
+ .collect(Collectors.toList());
+
+ exclusiveOptions.forEach(
+ option -> {
+ AbstractFormOption
exclusiveRequiredFormOption = null;
+ for (AbstractFormOption formItem : result)
{
+ if
(formItem.getField().equals(option.key())) {
+ exclusiveRequiredFormOption =
formItem;
+ break;
+ }
}
+ if (exclusiveRequiredFormOption == null) {
+ exclusiveRequiredFormOption =
+
wrapperToFormOption(connectorName, option, locale);
- if (option
- instanceof
RequiredOption.ConditionalRequiredOptions) {
-
RequiredOption.ConditionalRequiredOptions
- conditionalRequiredOptions =
-
(RequiredOption.ConditionalRequiredOptions)
- option;
-
- // we only support one field to
control a form option, so we
- // only need get condition key from the
- // first expression. And all
expression is 'or' and every
- // condition have the same key.
- String conditionKey =
- conditionalRequiredOptions
- .getExpression()
- .getCondition()
- .getOption()
- .key();
- List<Object> expectValueList = new
ArrayList<>();
- Expression expression =
-
conditionalRequiredOptions.getExpression();
- expectValueList.add(
- expression
- .getCondition()
- .getExpectValue()
- .toString());
- while (expression.hasNext()) {
- expression = expression.getNext();
- expectValueList.add(
- expression
- .getCondition()
- .getExpectValue()
- .toString());
- }
- List<AbstractFormOption> collect =
-
conditionalRequiredOptions.getRequiredOption()
- .stream()
- .map(
- requiredOption
-> {
- return
wrapperToFormOption(
-
connectorName,
-
requiredOption,
-
locale)
-
.withShow(
-
conditionKey,
-
expectValueList)
-
.withValidate(
-
ValidateBuilder
-
.builder()
-
.nonEmptyValidateBuilder()
-
.nonEmptyValidate());
- })
-
.collect(Collectors.toList());
- return collect;
+
result.add(exclusiveRequiredFormOption);
}
- throw new UnSupportWrapperException(
- connectorName, "Unknown",
option.toString());
- })
- .collect(Collectors.toList());
+ exclusiveRequiredFormOption.withValidate(
+ ValidateBuilder.builder()
+
.mutuallyExclusiveValidateBuilder()
+
.fields(exclusiveFields.toArray(new String[1]))
+
.mutuallyExclusiveValidate());
+ });
+ } else if (requiredOptions
+ instanceof
RequiredOption.ConditionalRequiredOptions) {
+ RequiredOption.ConditionalRequiredOptions
conditionalRequiredOptions =
+ (RequiredOption.ConditionalRequiredOptions)
requiredOptions;
+
+ // we only support one field to control a form option,
so we
+ // only need get condition key from the
+ // first expression. And all expression is 'or' and
every
+ // condition have the same key.
+ String conditionKey =
+ conditionalRequiredOptions
+ .getExpression()
+ .getCondition()
+ .getOption()
+ .key();
+ List<Object> expectValueList = new ArrayList<>();
+ Expression expression =
conditionalRequiredOptions.getExpression();
+
expectValueList.add(expression.getCondition().getExpectValue().toString());
+ while (expression.hasNext()) {
+ expression = expression.getNext();
+ expectValueList.add(
+
expression.getCondition().getExpectValue().toString());
+ }
- return formOptionsList;
+ conditionalRequiredOptions
+ .getRequiredOption()
+ .forEach(
+ option -> {
+ AbstractFormOption
conditionalRequiredFormItem = null;
+ for (AbstractFormOption formItem :
result) {
+ if
(formItem.getField().equals(option.key())) {
+
conditionalRequiredFormItem = formItem;
+ break;
+ }
+ }
+
+ if (conditionalRequiredFormItem ==
null) {
+ conditionalRequiredFormItem =
+ wrapperToFormOption(
+ connectorName,
option, locale);
+
result.add(conditionalRequiredFormItem);
+ }
+
+ if
(conditionalRequiredFormItem.getShow() == null) {
+
conditionalRequiredFormItem.withShow(
+ conditionKey,
expectValueList);
+ } else {
+ Map<String, Object> show =
+
conditionalRequiredFormItem.getShow();
+ String field =
+
show.get(Constants.SHOW_FIELD).toString();
+ if
(field.equals(conditionKey)) {
+ Set values =
+ (Set)
show.get(Constants.SHOW_VALUE);
+
values.addAll(expectValueList);
+ } else {
+ throw new
UnSupportWrapperException(
+ connectorName,
+
conditionalRequiredFormItem.getLabel(),
+ "Only support show
by one field");
+ }
+ }
+
+ if
(conditionalRequiredFormItem.getValidate() == null) {
+
conditionalRequiredFormItem.withValidate(
+
ValidateBuilder.builder()
+
.nonEmptyValidateBuilder()
+
.nonEmptyValidate());
+ }
+ });
+ }
+ });
+ return result;
}
private static AbstractFormOption wrapperToFormOption(
diff --git
a/seatunnel-server/seatunnel-dynamicform/src/main/java/org/apache/seatunnel/app/dynamicforms/AbstractFormOption.java
b/seatunnel-server/seatunnel-dynamicform/src/main/java/org/apache/seatunnel/app/dynamicforms/AbstractFormOption.java
index bc3e65c2..2f829b58 100644
---
a/seatunnel-server/seatunnel-dynamicform/src/main/java/org/apache/seatunnel/app/dynamicforms/AbstractFormOption.java
+++
b/seatunnel-server/seatunnel-dynamicform/src/main/java/org/apache/seatunnel/app/dynamicforms/AbstractFormOption.java
@@ -27,8 +27,10 @@ import lombok.Getter;
import lombok.NonNull;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
@Data
public abstract class AbstractFormOption<T extends AbstractFormOption, V
extends AbstractValidate> {
@@ -75,8 +77,9 @@ public abstract class AbstractFormOption<T extends
AbstractFormOption, V extends
this.show = new HashMap<>();
}
+ Set<Object> valueSet = new HashSet<>(values);
this.show.put(Constants.SHOW_FIELD, field);
- this.show.put(Constants.SHOW_VALUE, values);
+ this.show.put(Constants.SHOW_VALUE, valueSet);
return (T) this;
}
diff --git
a/seatunnel-server/seatunnel-dynamicform/src/main/java/org/apache/seatunnel/app/dynamicforms/FormStructureValidate.java
b/seatunnel-server/seatunnel-dynamicform/src/main/java/org/apache/seatunnel/app/dynamicforms/FormStructureValidate.java
index 74080b64..532c3691 100644
---
a/seatunnel-server/seatunnel-dynamicform/src/main/java/org/apache/seatunnel/app/dynamicforms/FormStructureValidate.java
+++
b/seatunnel-server/seatunnel-dynamicform/src/main/java/org/apache/seatunnel/app/dynamicforms/FormStructureValidate.java
@@ -42,11 +42,13 @@ public class FormStructureValidate {
List<String> showErrorList = validateShow(formStructure);
List<String> unionNonErrorList = validateUnionNonEmpty(formStructure);
List<String> exclusiveErrorList =
validateMutuallyExclusive(formStructure);
+ List<String> duplicateFormItemErrorList =
validateDuplicateFormItem(formStructure);
apiErrorList.addAll(localeErrorList);
apiErrorList.addAll(showErrorList);
apiErrorList.addAll(unionNonErrorList);
apiErrorList.addAll(exclusiveErrorList);
+ apiErrorList.addAll(duplicateFormItemErrorList);
if (apiErrorList.size() > 0) {
throw new FormStructureValidateException(formStructure.getName(),
apiErrorList);
@@ -267,4 +269,28 @@ public class FormStructureValidate {
return errorMessageList;
}
+
+ public static List<String> validateDuplicateFormItem(@NonNull
FormStructure formStructure) {
+ List fieldList = new ArrayList();
+ List errorFieldList = new ArrayList();
+ List errorMessage = new ArrayList();
+ formStructure
+ .getForms()
+ .forEach(
+ form -> {
+ if (fieldList.contains(form.getField())) {
+ errorFieldList.add(form.getField());
+ } else {
+ fieldList.add(form.getField());
+ }
+ });
+ if (errorFieldList.size() > 0) {
+ errorMessage.add(
+ String.format(
+ "DuplicateFormItemValidate failed, Duplicate form
items %s",
+ errorFieldList));
+ }
+
+ return errorMessage;
+ }
}
