import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import java.beans.PropertyDescriptor;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.TreeMap;
import java.util.concurrent.ExecutionException;
public class EntityHelper {
public static <T extends IRule> List<T> translate(InputStream stream, Class<T> clazz) throws IOException, IllegalAccessException, InstantiationException, ExecutionException, InvocationTargetException, NoSuchMethodException {
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
List<T> result = Lists.newArrayList();
while ((line = reader.readLine()) != null) {
String[] data = line.split(";");
T rule = clazz.newInstance();
for (int idx = 0; idx < data.length; idx++) {
BeanUtils.setProperty(rule, getProperty(clazz,(idx+1)).getName(), data[idx]);
}
result.add(rule);
}
if (reader != null) {
reader.close();
}
return result;
}
public static <T extends IRule> List<T> translate(ResultSet resultSet, Class<T> clazz) throws IOException, IllegalAccessException, InstantiationException, ExecutionException, InvocationTargetException, SQLException, NoSuchMethodException {
List<T> result = Lists.newArrayList();
ResultSetMetaData meta = resultSet.getMetaData();
int columnCount = meta.getColumnCount();
while (resultSet.next()) {
T instance = clazz.newInstance();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
String columnName = meta.getColumnName(columnIndex);
PropertyDescriptor prop = getProperty(clazz,columnName.toLowerCase());
if (prop != null) {
Method method = PropertyUtils.getWriteMethod(prop);
if (method != null){
method.invoke(instance, resultSet.getObject(columnIndex));
}
}
}
result.add(instance);
}
return result;
}
public static <T extends IRule> T translateRow(ResultSet resultSet, Class<T> clazz) throws Exception {
ResultSetMetaData meta = resultSet.getMetaData();
T instance = clazz.newInstance();
int columnCount = meta.getColumnCount();
while (resultSet.next()) {
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
String columnName = meta.getColumnName(columnIndex);
PropertyDescriptor prop = getProperty(clazz,columnName.toLowerCase());
if (prop != null) {
Method method = PropertyUtils.getWriteMethod(prop);
if (method != null){
method.invoke(instance, resultSet.getObject(columnIndex));
}
}
}
}
return instance;
}
public static <T extends IRule> List<String> translate(List<T> entities) throws ExecutionException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException {
List<String> result = Lists.newArrayList();
for (IRule rule : entities) {
if(!cache.containsKey(rule.getClass()))
cache.put(rule.getClass(),getMetaData(rule.getClass()));
TreeMap<Integer, PropertyDescriptor> props = cache.get(rule.getClass());
List<String> rowValues = Lists.newArrayList();
for (int key : props.keySet()) {
String columnValue = props.get(key).getReadMethod().invoke(rule).toString();
rowValues.add(columnValue);
}
result.add(StringUtils.join(rowValues, ';'));
}
return result;
}
private static PropertyDescriptor getProperty(Class<? extends IRule> clazz,int idx) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
if(!cache.containsKey(clazz)){
cache.put(clazz,getMetaData(clazz));
}
return cache.get(clazz).get(idx);
}
private static PropertyDescriptor getProperty(Class<? extends IRule> clazz,String name) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
if(!cacheWithName.containsKey(clazz)){
TreeMap<String,PropertyDescriptor> tmp=new TreeMap<String, PropertyDescriptor>();
TreeMap<Integer, PropertyDescriptor> meta = getMetaData(clazz);
for(int idx:meta.keySet()){
tmp.put(meta.get(idx).getName().toLowerCase(),meta.get(idx));
}
cacheWithName.put(clazz,tmp);
}
return cacheWithName.get(clazz).get(name);
}
private static HashMap<Class<? extends IRule>,TreeMap<Integer, PropertyDescriptor>> cache = new HashMap<Class<? extends IRule>, TreeMap<Integer, PropertyDescriptor>>();
private static HashMap<Class<? extends IRule>,TreeMap<String, PropertyDescriptor>> cacheWithName = new HashMap<Class<? extends IRule>, TreeMap<String, PropertyDescriptor>>();
private static TreeMap<Integer, PropertyDescriptor> getMetaData(Class<? extends IRule> clazz) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
if (clazz.isAnnotationPresent(Rule.class)) {
TreeMap<Integer, PropertyDescriptor> result = Maps.newTreeMap();
IRule instance = clazz.newInstance();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(ColumnSpec.class)) {
ColumnSpec spec = field.getAnnotation(ColumnSpec.class);
PropertyDescriptor propertyDescriptor = PropertyUtils.getPropertyDescriptor(instance, field.getName());
result.put(spec.order(), propertyDescriptor);
}
}
return result;
}
return null;
}
}