com.cherokeesoft.db.utils.graph.reader.AsteriskClassGraphReader Maven / Gradle / Ivy
package com.cherokeesoft.db.utils.graph.reader;
import com.cherokeesoft.db.utils.graph.DataGraphUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.ClassUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class AsteriskClassGraphReader implements ClassGraphReader {
private static final Pattern PATTERN = Pattern.compile("([a-zA-Z]+.*\\.\\*{1,2}|(\\*{1,2}))");
private final Class> aClass;
private final String field;
private final BiFunction, Class>, Boolean> filter;
public AsteriskClassGraphReader(Class> aClass, String field) {
this(aClass, field, (strings, aClass1) -> true);
}
public AsteriskClassGraphReader(Class> aClass, String field, BiFunction, Class>, Boolean> filter) {
this.aClass = aClass;
this.field = field;
if(!PATTERN.matcher(field).matches()) {
throw new IllegalArgumentException(String.format("Invalid format field %s", field));
}
this.filter = filter;
}
public List getGraph() {
List result = new ArrayList<>();
result.add(field);
try {
String[] split = field.split("\\.");
if(split.length != 0) {
List> res = new ArrayList<>();
goOverFields(res, new ArrayList<>(), this.aClass);
String ast = split[split.length - 1];
List joinedField = res.stream().map(v -> v.stream().collect(Collectors.joining("."))).collect(Collectors.toList());
String pattern = Arrays.stream(Arrays.copyOfRange(split, 0, split.length - 1)).collect(Collectors.joining("."));
if("*".equals(ast)) {
joinedField = res.stream()
.map(v -> v.toArray(new String[v.size()]))
.filter(v -> v.length == split.length)
.filter(v -> Arrays.stream(Arrays.copyOfRange(v, 0, v.length - 1)).collect(Collectors.joining(".")).startsWith(pattern))
.map( v -> Arrays.stream(v).collect(Collectors.joining(".")))
.collect(Collectors.toList());
} else if("**".equals(ast)) {
joinedField = joinedField.stream().filter(v -> v.startsWith(pattern)).collect(Collectors.toList());
} else {
throw new IllegalArgumentException("Invalid input format");
}
result.addAll(joinedField);
}
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void goOverFields(List> res, List parentSb, Class> aClass) {
if(!DataGraphUtils.isSimpleValueType(aClass)) {
Field[] declaredFields = aClass.getDeclaredFields();
if(declaredFields.length != 0) {
for(Field field: declaredFields) {
List sb = new ArrayList<>(parentSb);
sb.add(field.getName());
goOverFields(res, sb, field.getType());
}
}
} else {
res.add(parentSb);
}
}
}