3 changed files with 181 additions and 0 deletions
@ -0,0 +1,166 @@ |
|||||||
|
package com.jayway.jsonpath.internal.function.text; |
||||||
|
|
||||||
|
import com.jayway.jsonpath.internal.EvaluationContext; |
||||||
|
import com.jayway.jsonpath.internal.PathRef; |
||||||
|
import com.jayway.jsonpath.internal.function.ParamType; |
||||||
|
import com.jayway.jsonpath.internal.function.Parameter; |
||||||
|
import com.jayway.jsonpath.internal.function.PathFunction; |
||||||
|
|
||||||
|
import java.util.*; |
||||||
|
import java.util.function.Function; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* join values in an array, supply two grammars: |
||||||
|
* <p> |
||||||
|
* 1. [].join([delimiter],[..path]) |
||||||
|
* 2. $.join([delimiter],[..path]) |
||||||
|
*/ |
||||||
|
public class Join implements PathFunction { |
||||||
|
@Override |
||||||
|
public Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx, List<Parameter> parameters) { |
||||||
|
String delimiter = this.getDelimiterFromParameters(parameters); |
||||||
|
Collection<String> results = Collections.emptyList(); |
||||||
|
|
||||||
|
// [].join([..path])
|
||||||
|
if (ctx.configuration().jsonProvider().isArray(model)) { |
||||||
|
results = this.joinByArrayModel(model, ctx, parameters); |
||||||
|
} |
||||||
|
|
||||||
|
// $.join([delimiter],[..path])
|
||||||
|
if (null == results || results.size() == 0) { |
||||||
|
results = this.joinByParams(ctx, parameters); |
||||||
|
} |
||||||
|
|
||||||
|
if (null == results || results.size() == 0) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
return String.join(delimiter, results); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* get results by model |
||||||
|
* |
||||||
|
* @param model |
||||||
|
* @param ctx |
||||||
|
* @param parameters |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
protected Collection<String> joinByArrayModel(Object model, EvaluationContext ctx, List<Parameter> parameters) { |
||||||
|
Collection<String> resultList = new ArrayList<>(); |
||||||
|
List<Parameter> pathParams = Optional.ofNullable(parameters).orElseGet(Collections::emptyList) |
||||||
|
.stream().filter(item -> ParamType.PATH.equals(item.getType())).collect(Collectors.toList()); |
||||||
|
|
||||||
|
if (pathParams.size() == 0) { |
||||||
|
return this.arrayIterableToList(ctx, model, item -> null); |
||||||
|
} |
||||||
|
|
||||||
|
for (Parameter pathParam : pathParams) { |
||||||
|
List<String> list = this.arrayIterableToList(ctx, model, item -> { |
||||||
|
Object value = pathParam.getPath().evaluate(item, model, ctx.configuration()).getValue(); |
||||||
|
return this.arrayIterableToList(ctx, value, obj -> null); |
||||||
|
}); |
||||||
|
if (null == list || list.size() == 0) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
resultList.addAll(list); |
||||||
|
} |
||||||
|
return resultList; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* get results by params |
||||||
|
* |
||||||
|
* @param ctx |
||||||
|
* @param parameters |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
protected Collection<String> joinByParams(EvaluationContext ctx, List<Parameter> parameters) { |
||||||
|
if (null == parameters || parameters.size() == 0) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
List<Parameter> notJsonParams = parameters.stream().filter(item -> ParamType.PATH.equals(item.getType())).collect(Collectors.toList()); |
||||||
|
if (notJsonParams.size() == 0) { |
||||||
|
return parameters.stream().map(Parameter::getValue).filter(Objects::nonNull).map(Object::toString).collect(Collectors.toList()); |
||||||
|
} |
||||||
|
List<String> list = Parameter.toList(String.class, ctx, notJsonParams); |
||||||
|
return list.size() > 0 ? list : null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get delimiter |
||||||
|
* |
||||||
|
* @param parameters |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
protected String getDelimiterFromParameters(List<Parameter> parameters) { |
||||||
|
if (null != parameters && parameters.size() >= 1) { |
||||||
|
Parameter parameter = parameters.get(0); |
||||||
|
if (ParamType.JSON.equals(parameter.getType())) { |
||||||
|
return parameter.getValue().toString(); |
||||||
|
} |
||||||
|
} |
||||||
|
return ","; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* literal quantity type |
||||||
|
* |
||||||
|
* @param obj |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
protected boolean simpleType(Object obj) { |
||||||
|
if (null == obj) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
return obj instanceof Number || obj instanceof CharSequence || |
||||||
|
obj instanceof Boolean || obj instanceof Character; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* iterable |
||||||
|
* |
||||||
|
* @param ctx |
||||||
|
* @param model |
||||||
|
* @param itemIsNotSimpleFunc |
||||||
|
*/ |
||||||
|
protected List<String> arrayIterableToList(EvaluationContext ctx, Object model, Function<Object, List<String>> itemIsNotSimpleFunc) { |
||||||
|
if (null == model) { |
||||||
|
return Collections.emptyList(); |
||||||
|
} |
||||||
|
|
||||||
|
if (this.simpleType(model)) { |
||||||
|
return Collections.singletonList(model.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
boolean isArray = ctx.configuration().jsonProvider().isArray(model); |
||||||
|
if (!isArray) { |
||||||
|
return Collections.emptyList(); |
||||||
|
} |
||||||
|
|
||||||
|
List<String> resultList = new ArrayList<>(); |
||||||
|
Iterable<?> iterable = ctx.configuration().jsonProvider().toIterable(model); |
||||||
|
for (Object obj : iterable) { |
||||||
|
if (null == obj) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
boolean isSimpleType = this.simpleType(obj); |
||||||
|
if (isSimpleType) { |
||||||
|
resultList.add(obj.toString()); |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
List<String> items = itemIsNotSimpleFunc.apply(obj); |
||||||
|
if (null == items || items.size() == 0) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
resultList.addAll(items); |
||||||
|
} |
||||||
|
return resultList; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue