Support process control in aggregation #215
This commit is contained in:
@@ -43,6 +43,9 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import we.constants.CommonConstants;
|
||||
import we.exception.ExecuteScriptException;
|
||||
import we.fizz.component.ComponentHelper;
|
||||
import we.fizz.component.IComponent;
|
||||
import we.fizz.component.StepContextPosition;
|
||||
import we.fizz.input.ClientInputConfig;
|
||||
import we.fizz.input.Input;
|
||||
import we.fizz.input.InputConfig;
|
||||
@@ -116,14 +119,12 @@ public class Pipeline {
|
||||
}else {
|
||||
LinkedList<Step> opSteps = (LinkedList<Step>) steps.clone();
|
||||
Step step1 = opSteps.removeFirst();
|
||||
step1.beforeRun(stepContext, null);
|
||||
Mono<List<StepResponse>> result = createStep(step1).expand(response -> {
|
||||
Mono<List<StepResponse>> result = runStep(step1, null).expand(response -> {
|
||||
if (opSteps.isEmpty() || response.isStop()) {
|
||||
return Mono.empty();
|
||||
}
|
||||
Step step = opSteps.pop();
|
||||
step.beforeRun(stepContext, response);
|
||||
return createStep(step);
|
||||
return runStep(step, response);
|
||||
}).flatMap(response -> Flux.just(response)).collectList();
|
||||
return result.flatMap(clientResponse -> {
|
||||
return handleOutput(input);
|
||||
@@ -131,6 +132,23 @@ public class Pipeline {
|
||||
}
|
||||
}
|
||||
|
||||
private Mono<StepResponse> runStep(Step step, StepResponse response){
|
||||
List<IComponent> components = step.getComponents();
|
||||
if (components != null && components.size() > 0) {
|
||||
StepContextPosition stepCtxPos = new StepContextPosition(step.getName());
|
||||
return ComponentHelper.run(components, stepContext, stepCtxPos, (ctx, pos) -> {
|
||||
step.beforeRun(stepContext, null);
|
||||
return createStep(step).flatMap(r -> {
|
||||
ctx.addStepCircleResult(pos.getStepName());
|
||||
return Mono.just(r);
|
||||
});
|
||||
}).flatMap(sr -> Mono.just((StepResponse)sr));
|
||||
} else {
|
||||
step.beforeRun(stepContext, null);
|
||||
return createStep(step);
|
||||
}
|
||||
}
|
||||
|
||||
private Mono<AggregateResult> handleOutput(Input input){
|
||||
// 数据转换
|
||||
long t3 = System.currentTimeMillis();
|
||||
|
||||
@@ -22,7 +22,11 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.noear.snack.ONode;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -34,6 +38,12 @@ import org.springframework.web.reactive.function.client.WebClient;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
import we.fizz.component.ComponentHelper;
|
||||
import we.fizz.component.ComponentTypeEnum;
|
||||
import we.fizz.component.IComponent;
|
||||
import we.fizz.component.StepContextPosition;
|
||||
import we.fizz.component.circle.Circle;
|
||||
import we.fizz.component.condition.Condition;
|
||||
import we.fizz.input.Input;
|
||||
import we.fizz.input.InputConfig;
|
||||
import we.fizz.input.InputContext;
|
||||
@@ -57,6 +67,16 @@ public class Step {
|
||||
|
||||
private Map<String, InputConfig> requestConfigs = new HashMap<String, InputConfig>();
|
||||
|
||||
private List<IComponent> components;
|
||||
|
||||
public List<IComponent> getComponents() {
|
||||
return components;
|
||||
}
|
||||
|
||||
public void setComponents(List<IComponent> components) {
|
||||
this.components = components;
|
||||
}
|
||||
|
||||
public SoftReference<Pipeline> getWeakPipeline() {
|
||||
return weakPipeline;
|
||||
}
|
||||
@@ -78,6 +98,7 @@ public class Step {
|
||||
InputConfig inputConfig = InputFactory.createInputConfig(requestConfig);
|
||||
step.addRequestConfig((String)requestConfig.get("name"), inputConfig);
|
||||
}
|
||||
step.setComponents(ComponentHelper.buildComponents((List<Map<String, Object>>) config.get("components")));
|
||||
return step;
|
||||
}
|
||||
}
|
||||
@@ -112,16 +133,33 @@ public class Step {
|
||||
|
||||
public List<Mono> run() {
|
||||
List<Mono> monos = new ArrayList<Mono>();
|
||||
for(String name :inputs.keySet()) {
|
||||
Input input = inputs.get(name);
|
||||
for(String requestName :inputs.keySet()) {
|
||||
Input input = inputs.get(requestName);
|
||||
List<IComponent> components = input.getConfig().getComponents();
|
||||
if (components != null && components.size() > 0) {
|
||||
StepContextPosition stepCtxPos = new StepContextPosition(name, requestName);
|
||||
Mono<Object> result = ComponentHelper.run(components, stepContext, stepCtxPos, (ctx, pos) -> {
|
||||
if (input.needRun(ctx)) {
|
||||
return input.run().flatMap(r -> {
|
||||
ctx.addRequestCircleResult(pos.getStepName(), pos.getRequestName());
|
||||
return Mono.just(r);
|
||||
});
|
||||
}
|
||||
return Mono.just(new HashMap());
|
||||
});
|
||||
monos.add(result);
|
||||
} else {
|
||||
if (input.needRun(stepContext)) {
|
||||
Mono<Map> singleMono = input.run();
|
||||
monos.add(singleMono);
|
||||
}
|
||||
}
|
||||
}
|
||||
return monos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void afeterRun() {
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.http.codec.multipart.FilePart;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
import we.constants.CommonConstants;
|
||||
|
||||
/**
|
||||
@@ -146,6 +148,8 @@ public class StepContext<K, V> extends ConcurrentHashMap<K, V> {
|
||||
requests = new HashMap<>();
|
||||
stepResponse.setRequests(requests);
|
||||
requests.put(requestName, new HashMap<String, Object>());
|
||||
}else if(!requests.containsKey(requestName)) {
|
||||
requests.put(requestName, new HashMap<String, Object>());
|
||||
}
|
||||
return (Map<String, Object>) requests.get(requestName);
|
||||
}
|
||||
@@ -682,6 +686,161 @@ public class StepContext<K, V> extends ConcurrentHashMap<K, V> {
|
||||
return request.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Step的循环对象 <br>
|
||||
* Set the current circle item of step<br>
|
||||
* <br>
|
||||
*
|
||||
* @param stepName
|
||||
* @param item
|
||||
* @param index
|
||||
*/
|
||||
public void setStepCircleItem(String stepName, Object item, Integer index) {
|
||||
StepResponse stepResponse = (StepResponse) this.get(stepName);
|
||||
if (stepResponse == null) {
|
||||
return;
|
||||
}
|
||||
stepResponse.setItem(item);
|
||||
stepResponse.setIndex(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加Step的循环结果<br>
|
||||
* Add the result of current circle item <br>
|
||||
* <br>
|
||||
*
|
||||
* @param stepName
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void addStepCircleResult(String stepName) {
|
||||
StepResponse stepResponse = (StepResponse) this.get(stepName);
|
||||
if (stepResponse == null) {
|
||||
return;
|
||||
}
|
||||
List<Map<String, Object>> circle = (List<Map<String, Object>>) stepResponse.getCircle();
|
||||
if (circle == null) {
|
||||
circle = new ArrayList<>();
|
||||
stepResponse.setCircle(circle);
|
||||
}
|
||||
Map<String, Object> circleResult = new HashMap<>();
|
||||
circleResult.put("requests", deepCopy(stepResponse.getRequests()));
|
||||
circleResult.put("result", deepCopy(stepResponse.getResult()));
|
||||
circleResult.put("item", deepCopy(stepResponse.getItem()));
|
||||
circleResult.put("index", stepResponse.getIndex());
|
||||
circle.add(circleResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Step的循环对象<br>
|
||||
* Returns current circle item<br>
|
||||
*
|
||||
* @param stepName
|
||||
*/
|
||||
public Object getStepItem(String stepName) {
|
||||
StepResponse stepResponse = (StepResponse) this.get(stepName);
|
||||
if (stepResponse == null) {
|
||||
return null;
|
||||
}
|
||||
return stepResponse.getItem();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Step的循环结果<br>
|
||||
* Returns circle result list of step <br>
|
||||
*
|
||||
* @param stepName
|
||||
*/
|
||||
public List<Map<String, Object>> getStepCircle(String stepName) {
|
||||
StepResponse stepResponse = (StepResponse) this.get(stepName);
|
||||
if (stepResponse == null) {
|
||||
return null;
|
||||
}
|
||||
return stepResponse.getCircle();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求的循环对象<br>
|
||||
* Set current circle item of request <br>
|
||||
*
|
||||
* @param stepName
|
||||
* @param requestName
|
||||
* @param item
|
||||
*/
|
||||
public void setRequestCircleItem(String stepName, String requestName, Object item, Integer index) {
|
||||
Map<String, Object> request = getStepRequest(stepName, requestName);
|
||||
if (request == null) {
|
||||
return;
|
||||
}
|
||||
request.put("item", item);
|
||||
request.put("index", index);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求的循环结果<br>
|
||||
* Set current circle result of request <br>
|
||||
*
|
||||
* @param stepName
|
||||
* @param requestName
|
||||
*/
|
||||
public void addRequestCircleResult(String stepName, String requestName) {
|
||||
Map<String, Object> request = getStepRequest(stepName, requestName);
|
||||
if (request == null) {
|
||||
return;
|
||||
}
|
||||
List<Map<String, Object>> circle = (List<Map<String, Object>>) request.get("circle");
|
||||
if (circle == null) {
|
||||
circle = new ArrayList<>();
|
||||
request.put("circle", circle);
|
||||
}
|
||||
Map<String, Object> circleResult = new HashMap<>();
|
||||
circleResult.put("request", deepCopy(request.get("request")));
|
||||
circleResult.put("response", deepCopy(request.get("response")));
|
||||
circleResult.put("item", deepCopy(request.get("item")));
|
||||
circleResult.put("index", request.get("index"));
|
||||
circle.add(circleResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求的循环对象<br>
|
||||
* Returns the current circle item of request<br>
|
||||
*
|
||||
* @param stepName
|
||||
* @param requestName
|
||||
*/
|
||||
public List<Map<String, Object>> getRequestCircleItem(String stepName, String requestName) {
|
||||
Map<String, Object> request = getStepRequest(stepName, requestName);
|
||||
if (request == null) {
|
||||
return null;
|
||||
}
|
||||
return (List<Map<String, Object>>) request.get("circle");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求的循环结果<br>
|
||||
* Returns circle result list of request<br>
|
||||
*
|
||||
* @param stepName
|
||||
* @param requestName
|
||||
*/
|
||||
public Object getRequestCircle(String stepName, String requestName) {
|
||||
Map<String, Object> request = getStepRequest(stepName, requestName);
|
||||
if (request == null) {
|
||||
return null;
|
||||
}
|
||||
return request.get("item");
|
||||
}
|
||||
|
||||
private Object deepCopy(Object obj) {
|
||||
if(obj == null) {
|
||||
return obj;
|
||||
}
|
||||
if(obj.getClass().isPrimitive()) {
|
||||
return obj;
|
||||
}
|
||||
return JSON.parse(JSON.toJSONString(obj));
|
||||
}
|
||||
|
||||
public ConfigurableApplicationContext getApplicationContext(){
|
||||
return this.applicationContext;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package we.fizz;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -28,6 +29,12 @@ public class StepResponse {
|
||||
private Map<String, Map<String, Object>> requests;
|
||||
private Map result;
|
||||
private boolean stop;
|
||||
// circle item
|
||||
private Object item;
|
||||
// index of circle item
|
||||
private Integer index;
|
||||
// circle results
|
||||
private List<Map<String,Object>> circle;
|
||||
|
||||
public StepResponse(Step aStep, HashMap item, Map<String, Map<String, Object>> requests) {
|
||||
setStepName(aStep.getName());
|
||||
@@ -39,6 +46,14 @@ public class StepResponse {
|
||||
setResult(item);
|
||||
}
|
||||
|
||||
public void addRequest(String requestName, Map<String, Object> requestObj) {
|
||||
if (this.requests.containsKey(requestName)) {
|
||||
this.requests.get(requestName).putAll(requestObj);
|
||||
} else {
|
||||
this.requests.put(requestName, requestObj);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isStop() {
|
||||
return stop;
|
||||
}
|
||||
@@ -63,5 +78,23 @@ public class StepResponse {
|
||||
public void setResult(Map result) {
|
||||
this.result = result;
|
||||
}
|
||||
public Object getItem() {
|
||||
return item;
|
||||
}
|
||||
public void setItem(Object item) {
|
||||
this.item = item;
|
||||
}
|
||||
public List<Map<String, Object>> getCircle() {
|
||||
return circle;
|
||||
}
|
||||
public void setCircle(List<Map<String, Object>> circle) {
|
||||
this.circle = circle;
|
||||
}
|
||||
public Integer getIndex() {
|
||||
return index;
|
||||
}
|
||||
public void setIndex(Integer index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
159
fizz-core/src/main/java/we/fizz/component/ComponentHelper.java
Normal file
159
fizz-core/src/main/java/we/fizz/component/ComponentHelper.java
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package we.fizz.component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.noear.snack.ONode;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
import we.fizz.StepContext;
|
||||
import we.fizz.component.circle.Circle;
|
||||
import we.fizz.component.condition.Condition;
|
||||
|
||||
/**
|
||||
* Condition component
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
public class ComponentHelper {
|
||||
|
||||
/**
|
||||
* Converts step context to ONode
|
||||
*
|
||||
* @param stepContext context
|
||||
* @return
|
||||
*/
|
||||
public static ONode toONode(StepContext<String, Object> stepContext) {
|
||||
ONode o = null;
|
||||
synchronized (stepContext) {
|
||||
o = ONode.loadObj(stepContext);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
public static List<IComponent> buildComponents(List<Map<String, Object>> componentConfig) {
|
||||
List<IComponent> components = new ArrayList<>();
|
||||
|
||||
if (componentConfig != null && componentConfig.size() > 0) {
|
||||
for (Map<String, Object> m : componentConfig) {
|
||||
// condition
|
||||
if (ComponentTypeEnum.CONDITION.getCode().equals(m.get("type"))) {
|
||||
Condition c = JSON.parseObject(JSON.toJSONString(m), Condition.class);
|
||||
components.add(c);
|
||||
}
|
||||
|
||||
// circle
|
||||
if (ComponentTypeEnum.CIRCLE.getCode().equals(m.get("type"))) {
|
||||
Circle c = JSON.parseObject(JSON.toJSONString(m), Circle.class);
|
||||
components.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param components
|
||||
* @param stepContext
|
||||
* @param f
|
||||
*/
|
||||
public static Mono<Object> run(List<IComponent> components, StepContext<String, Object> stepContext,
|
||||
StepContextPosition stepCtxPos, BiFunction<StepContext, StepContextPosition, Mono> f) {
|
||||
if (components != null && components.size() > 0) {
|
||||
// conditions before circle component
|
||||
List<Condition> conditions = new ArrayList<>();
|
||||
Circle circle = null;
|
||||
for (IComponent component : components) {
|
||||
if (ComponentTypeEnum.CIRCLE == component.getType()) {
|
||||
circle = (Circle) component;
|
||||
}
|
||||
if (circle == null && ComponentTypeEnum.CONDITION == component.getType()) {
|
||||
conditions.add((Condition) component);
|
||||
}
|
||||
}
|
||||
|
||||
if (conditions != null && conditions.size() > 0) {
|
||||
ONode ctxNode = toONode(stepContext);
|
||||
for (Condition c : conditions) {
|
||||
if (!c.exec(ctxNode)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (circle != null) {
|
||||
return circle.exec(stepContext, stepCtxPos, f);
|
||||
}
|
||||
// // conditions before circle component
|
||||
// List<Condition> conditions1 = new ArrayList<>();
|
||||
// // conditions after circle component
|
||||
// List<Condition> conditions2 = new ArrayList<>();
|
||||
// Circle circle = null;
|
||||
// for (IComponent component : components) {
|
||||
// if (ComponentTypeEnum.CIRCLE == component.getType()) {
|
||||
// circle = (Circle) component;
|
||||
// }
|
||||
// if (circle == null && ComponentTypeEnum.CONDITION == component.getType()) {
|
||||
// conditions1.add((Condition) component);
|
||||
// }
|
||||
// if (circle != null && ComponentTypeEnum.CONDITION == component.getType()) {
|
||||
// conditions2.add((Condition) component);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (conditions1 != null && conditions1.size() > 0) {
|
||||
// ONode ctxNode = toONode(stepContext);
|
||||
// for (Condition c : conditions1) {
|
||||
// if (!c.exec(ctxNode)) {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (circle != null) {
|
||||
// return circle.exec(stepContext, (ctx) -> {
|
||||
// boolean canRun = true;
|
||||
// if (conditions2 != null && conditions2.size() > 0) {
|
||||
// ONode ctxNode = toONode(ctx);
|
||||
// for (Condition c : conditions2) {
|
||||
// if (!c.exec(ctxNode)) {
|
||||
// canRun = false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (canRun) {
|
||||
// return f.apply(ctx);
|
||||
// } else {
|
||||
// return Mono.empty();
|
||||
// }
|
||||
//
|
||||
// });
|
||||
// }
|
||||
}
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.fizz.component;
|
||||
|
||||
/**
|
||||
* Component Type
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
public enum ComponentTypeEnum {
|
||||
|
||||
CONDITION("condition"), CIRCLE("circle");
|
||||
|
||||
private String code;
|
||||
|
||||
private ComponentTypeEnum(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public static ComponentTypeEnum getEnumByCode(String code) {
|
||||
for (ComponentTypeEnum item : ComponentTypeEnum.values()) {
|
||||
if (item.getCode().equals(code)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.fizz.component;
|
||||
|
||||
/**
|
||||
* Data type of fixed value
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
public enum FixedDataTypeEnum{
|
||||
|
||||
NUMBER("number"), STRING("string"), BOOLEAN("boolean");
|
||||
|
||||
private String code;
|
||||
|
||||
private FixedDataTypeEnum(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
}
|
||||
34
fizz-core/src/main/java/we/fizz/component/IComponent.java
Normal file
34
fizz-core/src/main/java/we/fizz/component/IComponent.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package we.fizz.component;
|
||||
|
||||
/**
|
||||
* Component interface
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
public interface IComponent {
|
||||
|
||||
/**
|
||||
* Returns component type
|
||||
* @return
|
||||
*/
|
||||
public ComponentTypeEnum getType();
|
||||
|
||||
|
||||
}
|
||||
38
fizz-core/src/main/java/we/fizz/component/OperatorEnum.java
Normal file
38
fizz-core/src/main/java/we/fizz/component/OperatorEnum.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.fizz.component;
|
||||
|
||||
/**
|
||||
* Operator
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
public enum OperatorEnum {
|
||||
|
||||
EQ("eq"), NE("ne"), GT("gt"), GE("ge"), LT("lt"), LE("le"), CONTAINS("contains"), NOT_CONTAIN("notContain"), CONTAINS_ANY("containsAny"),
|
||||
IS_NULL("isNull"), IS_NOT_NULL("isNotNull"), IS_BLANK("isBlank"), IS_NOT_BLANK("isNotBlank"), IS_EMPTY("isEmpty"),
|
||||
IS_NOT_EMPTY("isNotEmpty");
|
||||
|
||||
private String code;
|
||||
|
||||
private OperatorEnum(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.fizz.component;
|
||||
|
||||
/**
|
||||
* Data type of reference value
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
public enum RefDataTypeEnum {
|
||||
|
||||
INT("int"), LONG("long"), FLOAT("float"), DOUBLE("double"), STRING("string"), BOOLEAN("boolean"), ARRAY("array");
|
||||
|
||||
private String code;
|
||||
|
||||
private RefDataTypeEnum(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package we.fizz.component;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
public class StepContextPosition {
|
||||
|
||||
private String stepName;
|
||||
private String requestName;
|
||||
|
||||
public StepContextPosition(String stepName) {
|
||||
this.stepName = stepName;
|
||||
}
|
||||
|
||||
public StepContextPosition(String stepName, String requestName) {
|
||||
this.stepName = stepName;
|
||||
this.requestName = requestName;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
if (this.requestName == null) {
|
||||
return this.stepName;
|
||||
}
|
||||
return this.stepName + ".requests." + this.requestName;
|
||||
}
|
||||
|
||||
}
|
||||
41
fizz-core/src/main/java/we/fizz/component/ValueTypeEnum.java
Normal file
41
fizz-core/src/main/java/we/fizz/component/ValueTypeEnum.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.fizz.component;
|
||||
|
||||
|
||||
/**
|
||||
* Value Type
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
public enum ValueTypeEnum {
|
||||
|
||||
FIXED("fixed"), REF("ref");
|
||||
|
||||
private String code;
|
||||
|
||||
private ValueTypeEnum(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
}
|
||||
280
fizz-core/src/main/java/we/fizz/component/circle/Circle.java
Normal file
280
fizz-core/src/main/java/we/fizz/component/circle/Circle.java
Normal file
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.fizz.component.circle;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.noear.snack.ONode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import lombok.Data;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import we.fizz.StepContext;
|
||||
import we.fizz.component.ComponentHelper;
|
||||
import we.fizz.component.ComponentTypeEnum;
|
||||
import we.fizz.component.IComponent;
|
||||
import we.fizz.component.StepContextPosition;
|
||||
import we.fizz.component.ValueTypeEnum;
|
||||
import we.fizz.component.condition.Condition;
|
||||
import we.fizz.exception.FizzRuntimeException;
|
||||
import we.fizz.input.PathMapping;
|
||||
import we.fizz.input.RPCInput;
|
||||
|
||||
/**
|
||||
* Circle component
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
public class Circle implements IComponent {
|
||||
|
||||
private static final String type = ComponentTypeEnum.CIRCLE.getCode();
|
||||
|
||||
private String desc;
|
||||
|
||||
private ValueTypeEnum dataSourceType;
|
||||
|
||||
private Object dataSource;
|
||||
|
||||
private List<Condition> execConditions;
|
||||
|
||||
private List<Condition> breakConditions;
|
||||
|
||||
@Override
|
||||
public ComponentTypeEnum getType() {
|
||||
return ComponentTypeEnum.getEnumByCode(type);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param desc [optional] description
|
||||
* @param dataSourceType [required] type of data source
|
||||
* @param dataSource [required] data source
|
||||
* @param execConditions [optional] conditions to execute current circle loop
|
||||
* item
|
||||
* @param breakConditions [optional] conditions to break circle
|
||||
*/
|
||||
public Circle(String desc, ValueTypeEnum dataSourceType, Object dataSource, List<Condition> execConditions,
|
||||
List<Condition> breakConditions) {
|
||||
this.desc = desc;
|
||||
this.dataSourceType = dataSourceType;
|
||||
this.dataSource = dataSource;
|
||||
this.execConditions = execConditions;
|
||||
this.breakConditions = breakConditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Current item
|
||||
*/
|
||||
private Object currentItem;
|
||||
|
||||
/**
|
||||
* Index of current item
|
||||
*/
|
||||
private Integer index;
|
||||
|
||||
/**
|
||||
* Fixed value of dataSource
|
||||
*/
|
||||
private Integer fixedValue;
|
||||
|
||||
/**
|
||||
* Reference value of dataSource
|
||||
*/
|
||||
private List<Object> refValue;
|
||||
|
||||
private boolean refReadFlag;
|
||||
|
||||
private Integer getFixedValue(ONode ctxNode) {
|
||||
if (fixedValue != null) {
|
||||
return fixedValue;
|
||||
}
|
||||
if (dataSource == null) {
|
||||
return fixedValue;
|
||||
}
|
||||
if (dataSource instanceof Integer || dataSource instanceof Long) {
|
||||
fixedValue = Integer.valueOf(dataSource.toString());
|
||||
if (fixedValue.intValue() < 1) {
|
||||
throw new FizzRuntimeException("invalid data source, fixed data source must be a positive integer");
|
||||
}
|
||||
return fixedValue;
|
||||
} else {
|
||||
throw new FizzRuntimeException("invalid data source, fixed data source must be a positive integer");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Object> getRefValue(ONode ctxNode) {
|
||||
if (refReadFlag) {
|
||||
return refValue;
|
||||
}
|
||||
Object value = PathMapping.getValueByPath(ctxNode, (String) dataSource);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Collection) {
|
||||
refValue = (List<Object>) value;
|
||||
return refValue;
|
||||
} else {
|
||||
throw new FizzRuntimeException("invalid data source, referenced data source must be a array");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next circle item, returns null if no item left or dataSource is null
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CircleItem next(ONode ctxNode) {
|
||||
if (ValueTypeEnum.FIXED.equals(dataSourceType)) {
|
||||
Integer total = this.getFixedValue(ctxNode);
|
||||
if (index == null) {
|
||||
index = 0;
|
||||
currentItem = index;
|
||||
return new CircleItem(currentItem, index);
|
||||
} else if (index.intValue() < total.intValue() - 1) {
|
||||
index = index + 1;
|
||||
currentItem = index;
|
||||
return new CircleItem(currentItem, index);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if (ValueTypeEnum.REF.equals(dataSourceType)) {
|
||||
List<Object> list = this.getRefValue(ctxNode);
|
||||
if (index == null) {
|
||||
index = 0;
|
||||
currentItem = list.get(index);
|
||||
return new CircleItem(currentItem, index);
|
||||
} else if (index.intValue() < list.size() - 1) {
|
||||
index = index + 1;
|
||||
currentItem = list.get(index);
|
||||
return new CircleItem(currentItem, index);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if execConditions are all true, false otherwise
|
||||
*
|
||||
* @param ctxNode
|
||||
* @return
|
||||
*/
|
||||
public boolean canExec(ONode ctxNode) {
|
||||
if (this.execConditions != null && this.execConditions.size() > 0) {
|
||||
try {
|
||||
for (Condition condition : execConditions) {
|
||||
if (!condition.exec(ctxNode)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (FizzRuntimeException e) {
|
||||
throw new FizzRuntimeException(type + " " + e.getMessage(), e.getCause());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if breakConditions are all true, false otherwise
|
||||
*
|
||||
* @param ctxNode
|
||||
* @return
|
||||
*/
|
||||
public boolean breakCircle(ONode ctxNode) {
|
||||
if (this.breakConditions != null && this.breakConditions.size() > 0) {
|
||||
try {
|
||||
for (Condition condition : breakConditions) {
|
||||
if (condition.exec(ctxNode)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (FizzRuntimeException e) {
|
||||
throw new FizzRuntimeException(type + " " + e.getMessage(), e.getCause());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Mono<Object> exec(StepContext<String, Object> stepContext, StepContextPosition stepCtxPos,
|
||||
BiFunction<StepContext, StepContextPosition, Mono> f) {
|
||||
ONode ctxNode = ComponentHelper.toONode(stepContext);
|
||||
CircleItem nextItem = this.next(ctxNode);
|
||||
if (nextItem != null) {
|
||||
return Mono.just(new CircleItemResult(nextItem, null)).expand(circleItemResult -> {
|
||||
// put nextItem to step context and ctxNode for further JSON path mapping
|
||||
CircleItem cItem = circleItemResult.nextItem;
|
||||
if (stepCtxPos.getRequestName() != null) {
|
||||
stepContext.setRequestCircleItem(stepCtxPos.getStepName(), stepCtxPos.getRequestName(),
|
||||
cItem.getItem(), cItem.getIndex());
|
||||
} else {
|
||||
stepContext.setStepCircleItem(stepCtxPos.getStepName(), cItem.getItem(), cItem.getIndex());
|
||||
}
|
||||
PathMapping.setByPath(ctxNode, stepCtxPos.getPath() + ".item", cItem.getItem(), true);
|
||||
PathMapping.setByPath(ctxNode, stepCtxPos.getPath() + ".index", cItem.getIndex(), true);
|
||||
|
||||
if (!this.canExec(ctxNode)) {
|
||||
return Mono.just(new CircleItemResult(this.next(ctxNode), null));
|
||||
}
|
||||
if (this.breakCircle(ctxNode)) {
|
||||
return Mono.empty();
|
||||
}
|
||||
return f.apply(stepContext, stepCtxPos).flatMap(r -> {
|
||||
CircleItem nextItem2 = this.next(ctxNode);
|
||||
if (nextItem2 == null) {
|
||||
return Mono.empty();
|
||||
}
|
||||
return Mono.just(new CircleItemResult(nextItem2, r));
|
||||
});
|
||||
}).flatMap(circleItemResult -> Flux.just(circleItemResult)).collectList().flatMap(list -> {
|
||||
if (list != null && list.size() > 0) {
|
||||
Collections.reverse(list);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (list.get(i).result != null) {
|
||||
return Mono.just(list.get(i).result);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Mono.empty();
|
||||
});
|
||||
} else {
|
||||
return Mono.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
class CircleItemResult {
|
||||
private CircleItem nextItem;
|
||||
private Object result;
|
||||
|
||||
public CircleItemResult(CircleItem nextItem, Object result) {
|
||||
this.nextItem = nextItem;
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package we.fizz.component.circle;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class CircleItem {
|
||||
|
||||
private Object item;
|
||||
|
||||
private Integer index;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.fizz.component.condition;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.noear.snack.ONode;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import we.fizz.component.ComponentTypeEnum;
|
||||
import we.fizz.component.IComponent;
|
||||
import we.fizz.component.OperatorEnum;
|
||||
import we.fizz.component.RefDataTypeEnum;
|
||||
import we.fizz.component.ValueTypeEnum;
|
||||
import we.fizz.exception.FizzRuntimeException;
|
||||
import we.fizz.input.PathMapping;
|
||||
|
||||
/**
|
||||
* Condition component
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class Condition implements IComponent {
|
||||
|
||||
private static final String type = ComponentTypeEnum.CONDITION.getCode();
|
||||
|
||||
private String desc;
|
||||
|
||||
private ConditionValue value1;
|
||||
|
||||
private OperatorEnum operator;
|
||||
|
||||
private ConditionValue value2;
|
||||
|
||||
@Override
|
||||
public ComponentTypeEnum getType() {
|
||||
return ComponentTypeEnum.getEnumByCode(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute condition
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
public boolean exec(ONode ctxNode) {
|
||||
if (value1 == null || operator == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean rs = false;
|
||||
try {
|
||||
Object v1 = null;
|
||||
if (ValueTypeEnum.FIXED.equals(value1.getType())) {
|
||||
v1 = value1.getValue();
|
||||
} else {
|
||||
v1 = PathMapping.getValueByPath(ctxNode, (String) value1.getValue());
|
||||
v1 = this.cast(value1.getRefDataType(), v1);
|
||||
}
|
||||
|
||||
Object v2 = null;
|
||||
if (value2 != null && value2.getType() != null) {
|
||||
if (ValueTypeEnum.FIXED.equals(value2.getType())) {
|
||||
v2 = value2.getValue();
|
||||
} else {
|
||||
v2 = PathMapping.getValueByPath(ctxNode, (String) value2.getValue());
|
||||
v2 = this.cast(value2.getRefDataType(), v2);
|
||||
}
|
||||
}
|
||||
|
||||
switch (operator) {
|
||||
case EQ:
|
||||
if (v1 == null && v2 == null) {
|
||||
rs = true;
|
||||
} else if (v1 != null && v2 != null) {
|
||||
rs = this.compare(v1, v2) == 0;
|
||||
}
|
||||
break;
|
||||
case NE:
|
||||
if (v1 == null && v2 == null) {
|
||||
rs = false;
|
||||
} else if ((v1 == null && v2 != null) || (v1 != null && v2 == null)) {
|
||||
rs = true;
|
||||
} else if (v1 != null && v2 != null) {
|
||||
rs = this.compare(v1, v2) != 0;
|
||||
}
|
||||
break;
|
||||
case GT:
|
||||
rs = this.compare(v1, v2) > 0;
|
||||
break;
|
||||
case GE:
|
||||
rs = this.compare(v1, v2) >= 0;
|
||||
break;
|
||||
case LT:
|
||||
rs = this.compare(v1, v2) < 0;
|
||||
break;
|
||||
case LE:
|
||||
rs = this.compare(v1, v2) <= 0;
|
||||
break;
|
||||
case CONTAINS:
|
||||
if (v1 == null) {
|
||||
rs = false;
|
||||
}
|
||||
if (v1 instanceof Collection && !(v2 instanceof Collection)) {
|
||||
Collection coll1 = (Collection) v1;
|
||||
Object el = v2;
|
||||
if (v2 instanceof Integer || v2 instanceof Long) {
|
||||
el = Long.valueOf(v2.toString());
|
||||
} else if (v2 instanceof Float || v2 instanceof Double) {
|
||||
el = Double.valueOf(v2.toString());
|
||||
}
|
||||
rs = CollectionUtils.contains(coll1.iterator(), el);
|
||||
} else if (!(v1 instanceof Collection)) {
|
||||
throw new FizzRuntimeException("value1 must be a collection");
|
||||
} else if (v2 instanceof Collection) {
|
||||
throw new FizzRuntimeException("value2 can not be a collection");
|
||||
}
|
||||
break;
|
||||
case NOT_CONTAIN:
|
||||
if (v1 == null) {
|
||||
rs = true;
|
||||
}
|
||||
if (v1 instanceof Collection && !(v2 instanceof Collection)) {
|
||||
Collection coll1 = (Collection) v1;
|
||||
Object el = v2;
|
||||
if (v2 instanceof Integer || v2 instanceof Long) {
|
||||
el = Long.valueOf(v2.toString());
|
||||
} else if (v2 instanceof Float || v2 instanceof Double) {
|
||||
el = Double.valueOf(v2.toString());
|
||||
}
|
||||
rs = !CollectionUtils.contains(coll1.iterator(), el);
|
||||
} else if (!(v1 instanceof Collection)) {
|
||||
throw new FizzRuntimeException("value1 must be a collection");
|
||||
} else if (v2 instanceof Collection) {
|
||||
throw new FizzRuntimeException("value2 can not be a collection");
|
||||
}
|
||||
break;
|
||||
case CONTAINS_ANY:
|
||||
if (v1 == null || v2 == null) {
|
||||
rs = false;
|
||||
}
|
||||
if (v1 instanceof Collection && v2 instanceof Collection) {
|
||||
Collection coll1 = (Collection) v1;
|
||||
Collection coll2 = (Collection) v2;
|
||||
rs = CollectionUtils.containsAny(coll1, coll2);
|
||||
} else if (!(v1 instanceof Collection)) {
|
||||
throw new FizzRuntimeException("value1 must be a collection");
|
||||
} else if (!(v2 instanceof Collection)) {
|
||||
throw new FizzRuntimeException("value2 must be a collection");
|
||||
}
|
||||
break;
|
||||
case IS_NULL:
|
||||
rs = v1 == null;
|
||||
break;
|
||||
case IS_NOT_NULL:
|
||||
rs = v1 != null;
|
||||
break;
|
||||
case IS_BLANK:
|
||||
rs = v1 == null || StringUtils.isBlank(v1.toString());
|
||||
break;
|
||||
case IS_NOT_BLANK:
|
||||
rs = v1 != null && StringUtils.isNotBlank(v1.toString());
|
||||
break;
|
||||
case IS_EMPTY:
|
||||
rs = v1 == null || (v1 instanceof Collection && ((Collection) v1).isEmpty())
|
||||
|| (v1 instanceof Map && ((Map) v1).isEmpty());
|
||||
break;
|
||||
case IS_NOT_EMPTY:
|
||||
if (v1 != null) {
|
||||
if (v1 instanceof Collection) {
|
||||
rs = !((Collection) v1).isEmpty();
|
||||
} else if (v1 instanceof Map) {
|
||||
rs = !((Map) v1).isEmpty();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} catch (FizzRuntimeException e) {
|
||||
String message = type + ": " + e.getMessage() + ", data=" + JSON.toJSONString(this);
|
||||
throw new FizzRuntimeException(message, e.getCause());
|
||||
}
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private int compare(Object v1, Object v2) {
|
||||
if (v1 == null || v2 == null) {
|
||||
throw new FizzRuntimeException("value1 and value2 can not be null");
|
||||
}
|
||||
if (v1 instanceof Boolean && v2 instanceof Boolean) {
|
||||
Boolean n1 = (Boolean) v1;
|
||||
Boolean n2 = (Boolean) v2;
|
||||
return n1.compareTo(n2);
|
||||
} else if ((v1 instanceof Integer || v1 instanceof Long || v1 instanceof Float || v1 instanceof Double)
|
||||
&& (v2 instanceof Integer || v2 instanceof Long || v2 instanceof Float || v2 instanceof Double)) {
|
||||
// compare value if both are numbers
|
||||
Double n1 = Double.valueOf(v1.toString());
|
||||
Double n2 = Double.valueOf(v2.toString());
|
||||
return n1.compareTo(n2);
|
||||
} else if (v1 instanceof String && v2 instanceof String) {
|
||||
String s1 = v1.toString();
|
||||
String s2 = v2.toString();
|
||||
return s1.compareTo(s2);
|
||||
} else {
|
||||
throw new FizzRuntimeException(
|
||||
"types of value1 and value2 are not consistent or not supported for comparision");
|
||||
}
|
||||
}
|
||||
|
||||
private Object cast(RefDataTypeEnum type, Object val) {
|
||||
if (type != null) {
|
||||
switch (type) {
|
||||
case INT:
|
||||
val = Integer.valueOf(val.toString());
|
||||
break;
|
||||
case LONG:
|
||||
val = Long.valueOf(val.toString());
|
||||
break;
|
||||
case FLOAT:
|
||||
val = Float.valueOf(val.toString());
|
||||
break;
|
||||
case DOUBLE:
|
||||
val = Double.valueOf(val.toString());
|
||||
break;
|
||||
case BOOLEAN:
|
||||
val = Boolean.valueOf(val.toString());
|
||||
break;
|
||||
case STRING:
|
||||
val = val.toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.fizz.component.condition;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import we.fizz.component.FixedDataTypeEnum;
|
||||
import we.fizz.component.RefDataTypeEnum;
|
||||
import we.fizz.component.ValueTypeEnum;
|
||||
|
||||
/**
|
||||
* Condition value
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ConditionValue {
|
||||
|
||||
private ValueTypeEnum type;
|
||||
|
||||
private FixedDataTypeEnum fixedDataType;
|
||||
|
||||
private RefDataTypeEnum refDataType;
|
||||
|
||||
private Object value;
|
||||
|
||||
public ConditionValue(ValueTypeEnum type, FixedDataTypeEnum fixedDataType, Object value) {
|
||||
this.type = type;
|
||||
this.fixedDataType = fixedDataType;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public ConditionValue(ValueTypeEnum type, RefDataTypeEnum refDataType, Object value) {
|
||||
this.type = type;
|
||||
this.refDataType = refDataType;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
package we.fizz.exception;
|
||||
|
||||
public class FizzRuntimeException extends RuntimeException {
|
||||
public FizzRuntimeException (String message){
|
||||
public FizzRuntimeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public FizzRuntimeException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,11 @@
|
||||
package we.fizz.input;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import we.fizz.component.IComponent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author linwaiwai
|
||||
@@ -30,9 +33,8 @@ public class InputConfig {
|
||||
private InputType type;
|
||||
protected Map<String, Object> dataMapping;
|
||||
protected Map<String, Object> configMap;
|
||||
|
||||
|
||||
private Map<String, Object> condition;
|
||||
private List<IComponent> components;
|
||||
|
||||
public Map<String, Object> getCondition() {
|
||||
return condition;
|
||||
@@ -72,6 +74,14 @@ public class InputConfig {
|
||||
this.fallback = fallback;
|
||||
}
|
||||
|
||||
public List<IComponent> getComponents() {
|
||||
return components;
|
||||
}
|
||||
|
||||
public void setComponents(List<IComponent> components) {
|
||||
this.components = components;
|
||||
}
|
||||
|
||||
public void parse(){
|
||||
|
||||
}
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
|
||||
package we.fizz.input;
|
||||
|
||||
import we.fizz.component.ComponentHelper;
|
||||
import we.fizz.exception.FizzRuntimeException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -56,6 +58,7 @@ public class InputFactory {
|
||||
}
|
||||
inputConfig.setType(typeEnum);
|
||||
inputConfig.setDataMapping((Map<String, Object>) config.get("dataMapping"));
|
||||
inputConfig.setComponents(ComponentHelper.buildComponents((List<Map<String, Object>>) config.get("components")));
|
||||
inputConfig.parse();
|
||||
return inputConfig;
|
||||
}
|
||||
|
||||
@@ -309,6 +309,7 @@ public class PathMapping {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// upper case header name
|
||||
if (list.size() > 5 && "headers".equals(list.get(4))) {
|
||||
String headerName = list.get(5).toUpperCase();
|
||||
|
||||
@@ -97,7 +97,7 @@ public class DubboInput extends RPCInput {
|
||||
Map<String, Object> group = new HashMap<>();
|
||||
group.put("request", request);
|
||||
group.put("response", response);
|
||||
this.stepResponse.getRequests().put(name, group);
|
||||
this.stepResponse.addRequest(name, group);
|
||||
|
||||
request.put("serviceName", config.getServiceName());
|
||||
request.put("version", config.getVersion());
|
||||
|
||||
@@ -91,7 +91,7 @@ public class GrpcInput extends RPCInput implements IInput {
|
||||
Map<String, Object> group = new HashMap<>();
|
||||
group.put("request", request);
|
||||
group.put("response", response);
|
||||
this.stepResponse.getRequests().put(name, group);
|
||||
this.stepResponse.addRequest(name, group);
|
||||
|
||||
request.put("serviceName", config.getServiceName());
|
||||
request.put("method", config.getMethod());
|
||||
|
||||
@@ -121,7 +121,7 @@ public class RequestInput extends RPCInput implements IInput{
|
||||
Map<String, Object> group = new HashMap<>();
|
||||
group.put("request", request);
|
||||
group.put("response", response);
|
||||
this.stepResponse.getRequests().put(name, group);
|
||||
this.stepResponse.addRequest(name, group);
|
||||
|
||||
HttpMethod method = HttpMethod.valueOf(config.getMethod().toUpperCase());
|
||||
request.put("method", method);
|
||||
|
||||
170
fizz-core/src/test/java/we/fizz/component/CircleTests.java
Normal file
170
fizz-core/src/test/java/we/fizz/component/CircleTests.java
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package we.fizz.component;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.noear.snack.ONode;
|
||||
|
||||
import we.fizz.component.circle.Circle;
|
||||
import we.fizz.component.circle.CircleItem;
|
||||
import we.fizz.component.condition.Condition;
|
||||
import we.fizz.component.condition.ConditionValue;
|
||||
/**
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
import we.fizz.input.PathMapping;
|
||||
|
||||
class CircleTests {
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Test
|
||||
void testNextFixedDataSource() {
|
||||
ONode ctxNode = ONode.load(new HashMap());
|
||||
|
||||
// FIXED data source
|
||||
Circle c = new Circle(null, ValueTypeEnum.FIXED, 3, null, null);
|
||||
CircleItem circleItem = c.next(ctxNode);
|
||||
assertEquals(0, (Integer) circleItem.getItem());
|
||||
|
||||
circleItem = c.next(ctxNode);
|
||||
assertEquals(1, (Integer) circleItem.getItem());
|
||||
|
||||
circleItem = c.next(ctxNode);
|
||||
assertEquals(2, (Integer) circleItem.getItem());
|
||||
|
||||
circleItem = c.next(ctxNode);
|
||||
assertEquals(null, circleItem);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNextRefDataSource() {
|
||||
ONode ctxNode = ONode.load(new HashMap());
|
||||
|
||||
List<String> list1 = new ArrayList<>();
|
||||
list1.add("1");
|
||||
list1.add("2");
|
||||
list1.add("3");
|
||||
PathMapping.setByPath(ctxNode, "data.list1", list1, true);
|
||||
|
||||
// REF data source
|
||||
Circle c = new Circle(null, ValueTypeEnum.REF, "data.list1", null, null);
|
||||
CircleItem circleItem = c.next(ctxNode);
|
||||
assertEquals("1", (String) circleItem.getItem());
|
||||
|
||||
circleItem = c.next(ctxNode);
|
||||
assertEquals("2", (String) circleItem.getItem());
|
||||
|
||||
circleItem = c.next(ctxNode);
|
||||
assertEquals("3", (String) circleItem.getItem());
|
||||
|
||||
circleItem = c.next(ctxNode);
|
||||
assertEquals(null, circleItem);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecCondition() {
|
||||
ONode ctxNode = ONode.load(new HashMap());
|
||||
|
||||
List<String> list1 = new ArrayList<>();
|
||||
list1.add("0");
|
||||
list1.add("1");
|
||||
list1.add("2");
|
||||
list1.add("3");
|
||||
list1.add("4");
|
||||
|
||||
PathMapping.setByPath(ctxNode, "data.list1", list1, true);
|
||||
|
||||
ConditionValue bValue1 = new ConditionValue(ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "3");
|
||||
ConditionValue bValue2 = new ConditionValue(ValueTypeEnum.REF, RefDataTypeEnum.STRING, "item");
|
||||
Condition c1 = new Condition(null, bValue1, OperatorEnum.NE, bValue2);
|
||||
|
||||
List<Condition> execConditions = new ArrayList<>();
|
||||
execConditions.add(c1);
|
||||
|
||||
Circle circle = new Circle(null, ValueTypeEnum.REF, "data.list1", execConditions, null);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
CircleItem circleItem = circle.next(ctxNode);
|
||||
PathMapping.setByPath(ctxNode, "item", circleItem.getItem(), true);
|
||||
PathMapping.setByPath(ctxNode, "index", circleItem.getIndex(), true);
|
||||
boolean rs = circle.canExec(ctxNode);
|
||||
assertEquals(i, circleItem.getIndex());
|
||||
if (i < 3) {
|
||||
assertEquals(true, rs);
|
||||
}
|
||||
if (i == 3) {
|
||||
assertEquals(false, rs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBreakCondition() {
|
||||
ONode ctxNode = ONode.load(new HashMap());
|
||||
|
||||
List<String> list1 = new ArrayList<>();
|
||||
list1.add("0");
|
||||
list1.add("1");
|
||||
list1.add("2");
|
||||
list1.add("3");
|
||||
list1.add("4");
|
||||
|
||||
PathMapping.setByPath(ctxNode, "data.list1", list1, true);
|
||||
|
||||
ConditionValue bValue1 = new ConditionValue(ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "3");
|
||||
ConditionValue bValue2 = new ConditionValue(ValueTypeEnum.REF, RefDataTypeEnum.STRING, "item");
|
||||
Condition c1 = new Condition(null, bValue1, OperatorEnum.EQ, bValue2);
|
||||
|
||||
List<Condition> breakConditions = new ArrayList<>();
|
||||
breakConditions.add(c1);
|
||||
|
||||
Circle circle = new Circle(null, ValueTypeEnum.REF, "data.list1", null, breakConditions);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
CircleItem circleItem = circle.next(ctxNode);
|
||||
PathMapping.setByPath(ctxNode, "item", circleItem.getItem(), true);
|
||||
PathMapping.setByPath(ctxNode, "index", circleItem.getIndex(), true);
|
||||
boolean rs = circle.breakCircle(ctxNode);
|
||||
assertEquals(i, circleItem.getIndex());
|
||||
if (i < 3) {
|
||||
assertEquals(false, rs);
|
||||
}
|
||||
if (i == 3) {
|
||||
assertEquals(true, rs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
327
fizz-core/src/test/java/we/fizz/component/ConditionTests.java
Normal file
327
fizz-core/src/test/java/we/fizz/component/ConditionTests.java
Normal file
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* Copyright (C) 2021 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package we.fizz.component;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.noear.snack.ONode;
|
||||
|
||||
import we.fizz.component.condition.Condition;
|
||||
import we.fizz.component.condition.ConditionValue;
|
||||
import we.fizz.input.PathMapping;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
class ConditionTests {
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
private static final Boolean TRUE = true;
|
||||
private static final Boolean FALSE = false;
|
||||
|
||||
@Test
|
||||
void testExec() {
|
||||
ONode ctxNode = ONode.load(new HashMap());
|
||||
|
||||
Map<String, Object> m = new HashMap<>();
|
||||
m.put("int", 1);
|
||||
m.put("long", 2);
|
||||
m.put("float", 3.1);
|
||||
m.put("double", 4.21);
|
||||
m.put("string_abcd", "abcd");
|
||||
m.put("string_1", "1");
|
||||
m.put("string_8", "8");
|
||||
m.put("string_blank", "");
|
||||
m.put("bool_true", true);
|
||||
m.put("bool_false", false);
|
||||
|
||||
List<String> list1 = new ArrayList<>();
|
||||
list1.add("0");
|
||||
list1.add("1");
|
||||
list1.add("2");
|
||||
list1.add("3");
|
||||
list1.add("4");
|
||||
|
||||
List<String> list2 = new ArrayList<>();
|
||||
list2.add("1");
|
||||
list2.add("3");
|
||||
list2.add("223");
|
||||
|
||||
List<Integer> intList = new ArrayList<>();
|
||||
intList.add(0);
|
||||
intList.add(1);
|
||||
intList.add(2);
|
||||
intList.add(3);
|
||||
intList.add(4);
|
||||
|
||||
List<Float> floatList = new ArrayList<>();
|
||||
floatList.add(0f);
|
||||
floatList.add(1f);
|
||||
floatList.add(2f);
|
||||
floatList.add(3f);
|
||||
floatList.add(4f);
|
||||
|
||||
PathMapping.setByPath(ctxNode, "data.m", m, true);
|
||||
PathMapping.setByPath(ctxNode, "data.list1", list1, true);
|
||||
PathMapping.setByPath(ctxNode, "data.list2", list2, true);
|
||||
PathMapping.setByPath(ctxNode, "data.intList", intList, true);
|
||||
PathMapping.setByPath(ctxNode, "data.floatList", floatList, true);
|
||||
PathMapping.setByPath(ctxNode, "data.emptyList", new ArrayList<>(), true);
|
||||
|
||||
// boolean
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, TRUE, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.BOOLEAN, TRUE, OperatorEnum.EQ, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, FALSE, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.BOOLEAN, FALSE, OperatorEnum.EQ, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, TRUE, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.BOOLEAN, FALSE, OperatorEnum.EQ, FALSE });
|
||||
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, FALSE, ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.BOOLEAN, "data.m.bool_true", OperatorEnum.EQ, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, FALSE, ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.BOOLEAN, "data.m.bool_false", OperatorEnum.EQ, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, TRUE, ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.BOOLEAN, "data.m.bool_true", OperatorEnum.EQ, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, FALSE, ValueTypeEnum.REF, null,
|
||||
"data.m.a", OperatorEnum.EQ, FALSE });
|
||||
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, TRUE, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.BOOLEAN, FALSE, OperatorEnum.GT, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, TRUE, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.BOOLEAN, FALSE, OperatorEnum.GE, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, TRUE, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.BOOLEAN, TRUE, OperatorEnum.GE, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, FALSE, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.BOOLEAN, TRUE, OperatorEnum.LT, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, FALSE, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.BOOLEAN, FALSE, OperatorEnum.LE, TRUE });
|
||||
|
||||
// number
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.NUMBER, 1, OperatorEnum.EQ, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.NUMBER, 2, OperatorEnum.EQ, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.NUMBER, 1.000, OperatorEnum.EQ, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.NUMBER, 2.1, OperatorEnum.EQ, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1.0, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.NUMBER, 1.000, OperatorEnum.EQ, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1.1, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.NUMBER, 2.1, OperatorEnum.EQ, FALSE });
|
||||
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1.1, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.NUMBER, 2.1, OperatorEnum.GT, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1.1, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.NUMBER, 0.1, OperatorEnum.GE, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1.1, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.NUMBER, 0.1, OperatorEnum.LT, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1.1, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.NUMBER, 4, OperatorEnum.LT, TRUE });
|
||||
|
||||
// collection<String>
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "2", OperatorEnum.CONTAINS, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.STRING, "data.m.string_1", OperatorEnum.CONTAINS, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.CONTAINS, FALSE });
|
||||
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "2", OperatorEnum.NOT_CONTAIN, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.STRING, "data.m.string_1", OperatorEnum.NOT_CONTAIN, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.NOT_CONTAIN, TRUE });
|
||||
|
||||
// collection contains any
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.ARRAY, "data.list2", OperatorEnum.CONTAINS_ANY, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.ARRAY, "data.intList", OperatorEnum.CONTAINS_ANY, FALSE });
|
||||
|
||||
// Collection<int>
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "2", OperatorEnum.CONTAINS, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.INT, "data.m.int", OperatorEnum.CONTAINS, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.FIXED,
|
||||
RefDataTypeEnum.INT, 2, OperatorEnum.CONTAINS, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.FIXED,
|
||||
RefDataTypeEnum.INT, 9, OperatorEnum.CONTAINS, FALSE });
|
||||
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "2", OperatorEnum.NOT_CONTAIN, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.INT, "data.m.int", OperatorEnum.NOT_CONTAIN, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.FIXED,
|
||||
RefDataTypeEnum.INT, 2, OperatorEnum.NOT_CONTAIN, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.FIXED,
|
||||
RefDataTypeEnum.INT, 9, OperatorEnum.NOT_CONTAIN, TRUE });
|
||||
|
||||
// Collection<Float>
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.floatList",
|
||||
ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "2", OperatorEnum.CONTAINS, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.floatList", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.INT, "data.m.int", OperatorEnum.CONTAINS, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.floatList",
|
||||
ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 2, OperatorEnum.CONTAINS, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.floatList",
|
||||
ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 2.0, OperatorEnum.CONTAINS, TRUE });
|
||||
|
||||
// String
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, null, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, null, OperatorEnum.EQ, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, null, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, null, OperatorEnum.EQ, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, null, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "1", OperatorEnum.EQ, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "1", ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "1", OperatorEnum.EQ, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "1", ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "21", OperatorEnum.EQ, FALSE });
|
||||
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, null, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, null, OperatorEnum.NE, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, null, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, null, OperatorEnum.NE, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, null, ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "1", OperatorEnum.NE, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "1", ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "1", OperatorEnum.NE, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "1", ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "21", OperatorEnum.NE, TRUE });
|
||||
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "1", ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "21", OperatorEnum.GT, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "11", ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "21", OperatorEnum.GT, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "11", ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "21", OperatorEnum.GE, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "11", ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "21", OperatorEnum.LT, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "11", ValueTypeEnum.FIXED,
|
||||
FixedDataTypeEnum.STRING, "21", OperatorEnum.LE, TRUE });
|
||||
|
||||
// Is null
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.IS_NULL, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8",
|
||||
ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.IS_NULL, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", null, null, null,
|
||||
OperatorEnum.IS_NULL, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", null, null, null,
|
||||
OperatorEnum.IS_NULL, FALSE });
|
||||
|
||||
// Is not null
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.IS_NOT_NULL, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8",
|
||||
ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.IS_NOT_NULL, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", null, null, null,
|
||||
OperatorEnum.IS_NOT_NULL, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", null, null, null,
|
||||
OperatorEnum.IS_NOT_NULL, TRUE });
|
||||
|
||||
// Is Blank
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.IS_BLANK, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8",
|
||||
ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.IS_BLANK, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", null, null, null,
|
||||
OperatorEnum.IS_BLANK, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", null, null, null,
|
||||
OperatorEnum.IS_BLANK, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_blank", null, null,
|
||||
null, OperatorEnum.IS_BLANK, TRUE });
|
||||
|
||||
// Is not Blank
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.IS_NOT_BLANK, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8",
|
||||
ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.IS_NOT_BLANK, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", null, null, null,
|
||||
OperatorEnum.IS_NOT_BLANK, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", null, null, null,
|
||||
OperatorEnum.IS_NOT_BLANK, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_blank", null, null,
|
||||
null, OperatorEnum.IS_NOT_BLANK, FALSE });
|
||||
|
||||
// Is empty
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.IS_EMPTY, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.IS_EMPTY, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", null, null, null,
|
||||
OperatorEnum.IS_EMPTY, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", null, null, null,
|
||||
OperatorEnum.IS_EMPTY, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.emptyList", null, null, null,
|
||||
OperatorEnum.IS_EMPTY, TRUE });
|
||||
|
||||
// Is not empty
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.IS_NOT_EMPTY, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF,
|
||||
RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.IS_NOT_EMPTY, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", null, null, null,
|
||||
OperatorEnum.IS_NOT_EMPTY, FALSE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", null, null, null,
|
||||
OperatorEnum.IS_NOT_EMPTY, TRUE });
|
||||
this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.emptyList", null, null, null,
|
||||
OperatorEnum.IS_NOT_EMPTY, FALSE });
|
||||
|
||||
}
|
||||
|
||||
private void run(ONode ctxNode, Object[] item) {
|
||||
ConditionValue bValue1 = null;
|
||||
if (item[1] instanceof FixedDataTypeEnum) {
|
||||
bValue1 = new ConditionValue((ValueTypeEnum) item[0], (FixedDataTypeEnum) item[1], item[2]);
|
||||
} else {
|
||||
bValue1 = new ConditionValue((ValueTypeEnum) item[0], (RefDataTypeEnum) item[1], item[2]);
|
||||
}
|
||||
ConditionValue bValue2 = null;
|
||||
if (item[3] != null) {
|
||||
if (item[4] instanceof FixedDataTypeEnum) {
|
||||
bValue2 = new ConditionValue((ValueTypeEnum) item[3], (FixedDataTypeEnum) item[4], item[5]);
|
||||
} else {
|
||||
bValue2 = new ConditionValue((ValueTypeEnum) item[3], (RefDataTypeEnum) item[4], item[5]);
|
||||
}
|
||||
}
|
||||
Condition c = new Condition(null, bValue1, (OperatorEnum) item[6], bValue2);
|
||||
boolean rs = c.exec(ctxNode);
|
||||
boolean expected = (boolean) item[7];
|
||||
assertEquals(expected, rs);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -163,4 +163,31 @@ class PathMappingTests {
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testArray() {
|
||||
ONode ctxNode = ONode.load(new HashMap());
|
||||
|
||||
Map<String, Object> m = new HashMap<>();
|
||||
m.put("a", "1");
|
||||
m.put("b", "1");
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add("0");
|
||||
list.add("1");
|
||||
list.add("2");
|
||||
list.add("3");
|
||||
list.add("4");
|
||||
|
||||
PathMapping.setByPath(ctxNode, "data.m", m, true);
|
||||
|
||||
PathMapping.setByPath(ctxNode, "data.arr", list, true);
|
||||
|
||||
Object abcVal1 = PathMapping.getValueByPath(ctxNode, "data.arr[0]");
|
||||
assertEquals("0", (String)abcVal1);
|
||||
Object abcVal2 = PathMapping.getValueByPath(ctxNode, "data.arr[-1]");
|
||||
assertEquals("4", (String)abcVal2);
|
||||
System.out.println(abcVal1);
|
||||
System.out.println(abcVal2);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user