package org.zstack.sdk;
import org.apache.commons.beanutils.PropertyUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.util.Arrays.asList;
/**
* Created by xing5 on 2016/12/9.
*/
public class ApiResult {
ErrorCode error;
private String resultString;
public ErrorCode getError() {
return error;
}
void setError(ErrorCode error) {
this.error = error;
}
void setResultString(String resultString) {
this.resultString = resultString;
}
private static Object getProperty(Object bean, Iterator<String> it) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
String path = it.next();
if (bean instanceof Map) {
Pattern re = Pattern.compile("(.*)\\[(\\d+)]");
Matcher m = re.matcher(path);
if (m.find()) {
path = String.format("(%s)[%s]", m.group(1), m.group(2));
}
}
Object val = PropertyUtils.getProperty(bean, path);
if (it.hasNext()) {
return getProperty(val, it);
} else {
return val;
}
}
public static Object getProperty(Object bean, String path) {
List<String> paths = asList(path.split("\\."));
try {
return getProperty(bean, paths.iterator());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static void setProperty(Object bean, Iterator<String> it, String fieldName, Object val) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
if (it.hasNext()) {
bean = getProperty(bean, it);
}
if (bean instanceof Map) {
Pattern re = Pattern.compile("(.*)\\[(\\d+)]");
Matcher m = re.matcher(fieldName);
if (m.find()) {
fieldName = String.format("(%s)[%s]", m.group(1), m.group(2));
}
}
PropertyUtils.setProperty(bean, fieldName, val);
}
public static void setProperty(Object bean, String path, Object val) {
List<String> paths = asList(path.split("\\."));
String fieldName = paths.get(paths.size()-1);
paths = paths.subList(0, paths.size()-1);
try {
setProperty(bean, paths.iterator(), fieldName, val);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
<T> T getResult(Class<T> clz) {
if (resultString == null || resultString.isEmpty()) {
return null;
}
Map m = ZSClient.gson.fromJson(resultString, LinkedHashMap.class);
T ret = ZSClient.gson.fromJson(resultString, clz);
if (!m.containsKey("schema")) {
return ret;
}
Map<String, String> schema = (Map) m.get("schema");
try {
for (String path : schema.keySet()) {
String src = schema.get(path);
String dst = SourceClassMap.srcToDstMapping.get(src);
if (dst == null) {
//TODO: warning
continue;
}
Object bean = getProperty(ret, path);
if (bean.getClass().getName().equals(dst)) {
// not an inherent object
continue;
}
Class dstClz = Class.forName(dst);
Object source = getProperty(m, path);
Object dstBean = ZSClient.gson.fromJson(ZSClient.gson.toJson(source), dstClz);
setProperty(ret, path, dstBean);
}
return ret;
} catch (Exception e) {
throw new ApiException(e);
}
}
}