package ddth.dasp.framework.utils;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import ddth.dasp.common.utils.JsonUtils;
public class DPathUtils {
private final static Pattern PATTERN_INDEX = Pattern.compile("^\\[(\\d+)\\]$");
/**
* Extracts a value from the target object using DPath expression (generic
* version).
*
* @param target
* @param dPath
* @param clazz
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getValue(final Object target, final String dPath, final Class<T> clazz) {
Object temp = getValue(target, dPath);
if (temp == null) {
return null;
}
if (clazz.isAssignableFrom(temp.getClass())) {
return (T) temp;
}
if (clazz == String.class) {
return (T) temp.toString();
}
return null;
}
/**
* Extracts a value from the target object using DPath expression.
*
* @param target
* @param dPath
*/
public static Object getValue(final Object target, final String dPath) {
String[] paths = dPath.split("\\.");
Object result = target;
for (String path : paths) {
result = extractValue(result, path);
}
return result;
}
/**
* Sets a value to the target object using DPath expression.
*
* @param target
* @param dPath
* @param value
*/
@SuppressWarnings("unchecked")
public static void setValue(final Object target, final String dPath, final Object value) {
String[] paths = dPath.split("\\.");
Object cursor = target;
// "seek"to the correct position
for (int i = 0; i < paths.length - 1; i++) {
cursor = extractValue(cursor, paths[i]);
}
String index = paths[paths.length - 1];
Matcher m = PATTERN_INDEX.matcher(index);
if (m.matches() || "[]".equals(index)) {
int i = "[]".equals(index) ? Integer.MAX_VALUE : Integer.parseInt(m.group(1));
if (cursor instanceof List<?>) {
List<Object> temp = (List<Object>) cursor;
if (i < 0) {
throw new IllegalArgumentException("Invalid index [" + i + "]!");
}
if (i >= temp.size()) {
temp.add(value);
} else {
temp.remove(i);
temp.add(i, value);
}
} else {
throw new IllegalArgumentException("Target object is not a list or readonly!");
}
} else if (cursor instanceof Map<?, ?>) {
((Map<Object, Object>) cursor).put(index, value);
} else {
throw new IllegalArgumentException("Target object is not writable!");
}
}
private static Object extractValue(Object target, String index) {
if (target == null) {
return null;
}
Matcher m = PATTERN_INDEX.matcher(index);
if (m.matches()) {
int i = Integer.parseInt(m.group(1));
if (target instanceof Object[]) {
return ((Object[]) target)[i];
}
if (target instanceof List<?>) {
return ((List<?>) target).get(i);
}
throw new IllegalArgumentException("Expect an array or list!");
}
if (target instanceof Map<?, ?>) {
return ((Map<?, ?>) target).get(index);
}
throw new IllegalArgumentException();
}
public static void main(String[] args) {
String jsonString = "{\"columns\":{},\"sqls\":{}}";
Map<?, ?> data = JsonUtils.fromJson(jsonString, Map.class);
String path = "sqls.insert";
System.out.println(getValue(data, path));
setValue(data, path, "INSERT INTO table_name (col1) VALUES (value1)");
System.out.println(getValue(data, path));
System.out.println(data);
}
}