
chaschev.lang.OpenBean Maven / Gradle / Ivy
package chaschev.lang;
import chaschev.lang.reflect.ClassDesc;
import chaschev.lang.reflect.ConstructorDesc;
import chaschev.lang.reflect.MethodDesc;
import chaschev.util.Exceptions;
import com.google.common.base.Optional;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.FluentIterable;
import java.lang.reflect.Field;
import java.util.*;
import static chaschev.lang.Lists2.projectMethod;
import static java.util.Arrays.asList;
/**
* User: chaschev
* Date: 5/20/13
*/
public class OpenBean {
public static Map putAll(Map dest, Object src) {
try {
for (Field field : OpenBean.getClassDesc(src.getClass()).fields) {
final Object v = field.get(src);
dest.put(field.getName(), v);
}
return dest;
} catch (IllegalAccessException e) {
throw Exceptions.runtime(e);
}
}
public static Object putAll(Object dest, Map src) {
try {
for (Field field : OpenBean.getClassDesc(dest.getClass()).fields) {
final String name = field.getName();
if (src.containsKey(name)) {
final Object v = src.get(name);
field.set(dest, v);
}
}
return dest;
} catch (IllegalAccessException e) {
throw Exceptions.runtime(e);
}
}
public static ClassDesc getClassDesc(Class aClass) {
return ClassDesc.getClassDesc(aClass);
}
public static Optional getFieldValue(Object object, String fieldName, Class tClass) {
try {
Field field = _getField(object, fieldName);
if(field == null){
return Optional.absent();
}
return Optional.of((T)field.get(object));
} catch (IllegalAccessException e) {
throw Exceptions.runtime(e);
}
}
public static Object getFieldValue(Object object, String fieldName) {
try {
return _getField(object, fieldName).get(object);
} catch (IllegalAccessException e) {
throw Exceptions.runtime(e);
}
}
public static Object getOrInitCollection(Object object, String fieldName) {
try {
final Field collectionField = _getField(object, fieldName);
final Class> aClass = collectionField.getType();
Object value = collectionField.get(object);
if (value == null) {
if (List.class.isAssignableFrom(aClass)) {
value = new ArrayList();
} else if (Set.class.isAssignableFrom(aClass)) {
value = new HashSet();
} else if (Map.class.isAssignableFrom(aClass)) {
value = new HashMap();
} else {
throw new IllegalStateException("could not init collection/map for field: " + fieldName + " of class " + object.getClass());
}
collectionField.set(object, value);
}
return value;
} catch (IllegalAccessException e) {
throw Exceptions.runtime(e);
}
}
public static Optional getField(Object object, String fieldName) {
return Optional.fromNullable(_getField(object, fieldName));
}
private static Field _getField(Object object, String fieldName) {
return getClassDesc(object.getClass()).getField(fieldName);
}
public static Optional getMethod(Object object, String methodName, Object... params) {
MethodDesc methodDesc = getClassDesc(object.getClass()).getMethodDesc(methodName, false, params);
return Optional.fromNullable(methodDesc);
}
public static void setField(Object object, String fieldName, Object value) {
try {
_getField(object, fieldName).set(object, value);
} catch (IllegalAccessException e) {
throw Exceptions.runtime(e);
}
}
public static void copyFields(Object dest, Object src) {
copyFields(dest, src, DEFAULT_HANDLER);
}
public static void copyFields(Object dest, Map src) {
copyFields(dest, src, DEFAULT_HANDLER);
}
public static abstract class CustomCopyHandler {
public boolean handle(Field field1, Field field2, Object dest, Object src, String name) throws Exception {
return handle(field1, field2.get(dest), src, name);
}
public boolean handle(Field destField, Object srcValue, Object dest, String name) throws Exception {
throw new UnsupportedOperationException("todo");
}
}
private static final CustomCopyHandler DEFAULT_HANDLER = new CustomCopyHandler() {
@Override
public final boolean handle(Field field1, Field field2, Object dest, Object src, String name) throws Exception {
field1.set(dest, field2.get(src));
return true;
}
@Override
public boolean handle(Field destField, Object dest, Object srcValue, String name) throws Exception {
final Class> destClass = destField.getType();
if (destClass.isEnum() && srcValue instanceof String) {
srcValue = Enum.valueOf((Class) destClass, (String) srcValue);
}
try {
destField.set(dest, srcValue);
} catch (Exception e) {
throw Exceptions.runtime(e);
}
return true;
}
};
public static void copyFields(Object dest, Map src, final CustomCopyHandler handler) {
final ClassDesc destClassDesc = getClassDesc(dest.getClass());
try {
for (Map.Entry entry : src.entrySet()) {
final String name = (String) entry.getKey();
final Field destField = destClassDesc.getField(name);
if (destField == null) {
continue;
}
final Object srcValue = entry.getValue();
if (!(handler != null && handler.handle(destField, dest, srcValue, name))) {
DEFAULT_HANDLER.handle(destField, dest, srcValue, name);
}
}
} catch (Exception e) {
throw Exceptions.runtime(e);
}
}
public static void copyFields(Object dest, Object src, final CustomCopyHandler handler) {
final ClassDesc destClassDesc = getClassDesc(dest.getClass());
final ClassDesc srcClassDesc = getClassDesc(src.getClass());
int i1 = 0, i2 = 0;
final int l1 = destClassDesc.fields.length;
final int l2 = srcClassDesc.fields.length;
try {
while (true) {
final Field field1 = destClassDesc.fields[i1];
final Field field2 = srcClassDesc.fields[i2];
final String name1 = field1.getName();
final String name2 = field2.getName();
final int r = name1.compareTo(name2);
if (r == 0) {
if (handler == null || !handler.handle(field1, field2, dest, src, name1)) {
DEFAULT_HANDLER.handle(field1, field2, dest, src, name1);
}
i1++;
i2++;
if (i1 >= l1 || i2 >= l2) break;
} else if (r < 0) {
i1++;
if (i1 >= l1) break;
} else {
i2++;
if (i2 >= l2) break;
}
}
} catch (Exception e) {
throw Exceptions.runtime(e);
}
}
private static boolean isClass(Object object) {
return object instanceof Class;
}
public static Object getStaticFieldValue(Class aClass, String name) {
try {
final Field field = OpenBean.getClassDesc(aClass).getStaticField(name);
if (field == null) {
throw new RuntimeException("no such field '" + name + "' " + " in class " + aClass);
}
return field.get(aClass);
} catch (IllegalAccessException e) {
throw Exceptions.runtime(e);
}
}
public static Object invokeStatic(Class aClass, String name, Object... args) {
try {
final MethodDesc method = OpenBean.getClassDesc(aClass).getStaticMethodDesc(name, false);
if (method == null) {
throw new RuntimeException("no such method '" + name + "' " + " in class " + aClass);
}
return method.invoke(aClass, args);
} catch (Exception e) {
throw Exceptions.runtime(e);
}
}
public static Object invoke(Object object, String name, Object... args) {
try {
final MethodDesc method = OpenBean.getClassDesc(object.getClass()).getMethodDesc(name, false, args);
if (method == null) {
throw new RuntimeException("no such method '" + name + "' " + " in object " + object.getClass());
}
return method.invoke(object, args);
} catch (Exception e) {
throw Exceptions.runtime(e);
}
}
public static Object newByClass(String className, Object... params) {
return newByClass(className, false, params);
}
public static Object newByClassStrict(String className, Object... params) {
return newByClass(className, true, params);
}
private static Object newByClass(String className, boolean strictly, Object... params) {
try {
return newInstance(Class.forName(className), strictly, params);
} catch (ClassNotFoundException e) {
throw Exceptions.runtime(e);
}
}
public static T newInstance(Class extends T> aClass, Object... params) {
return newInstance(aClass, false, params);
}
public static T newInstanceStrict(Class aClass, Object... params){
return newInstance(aClass, true, params);
}
private static T newInstance(Class aClass, boolean strictly, Object... params){
ConstructorDesc desc = getConstructorDesc(aClass, strictly, params);
if(desc == null){
throw new chaschev.lang.reflect.NoSuchMethodException("constructor not found" +
", class = " + aClass.getSimpleName() +
", strict = " + strictly +
", params = " + Arrays.asList(params));
}
return desc.newInstance(params);
}
public static ConstructorDesc getConstructorDesc(Class aClass, Object... params) {
return getConstructorDesc(aClass, false, params);
}
public static ConstructorDesc getConstructorDescStrict(Class aClass, Object... params) {
return getConstructorDesc(aClass, true, params);
}
private static ConstructorDesc getConstructorDesc(Class aClass, boolean strictly, Object... params) {
return getClassDesc(aClass).getConstructorDesc(strictly, params);
}
public static ConstructorDesc getConstructorDesc(Class aClass, Class... classes) {
return getConstructorDesc(aClass, false, classes);
}
public static ConstructorDesc getConstructorDescStrict(Class aClass, Class... classes) {
return getConstructorDesc(aClass, true, classes);
}
private static ConstructorDesc getConstructorDesc(Class aClass, boolean strictly, Class... classes) {
return getClassDesc(aClass).getConstructorDesc(strictly, classes);
}
public static Iterable fieldsOfType(Object obj, final Class> aClass) {
return fieldsOfType(obj, aClass, false);
}
public static Iterable fieldsOfType(Object obj, final Class> aClass, final boolean strict) {
return fieldsOfType(obj.getClass(), aClass, strict);
}
public static Iterable fieldsOfType(Class> objClass, final Class> fieldClass){
return fieldsOfType(objClass, fieldClass, false);
}
public static List> methodsReturning(Object obj, final Class extends T> returnClass){
return methodsReturning(obj.getClass(), returnClass);
}
public static List> methodsReturning(Class> objClass, final Class extends T> returnClass){
return methodsReturning(objClass, returnClass, false);
}
public static List> methodsReturning(Class> objClass, final Class extends T> returnClass, boolean strict){
List> result = new ArrayList>(4);
for (MethodDesc method : getClassDesc(objClass).methods) {
Class> actualReturnType = method.getMethod().getReturnType();
if(!strict){
if(returnClass.isAssignableFrom(actualReturnType)){
result.add(method);
}
}else{
if(returnClass ==actualReturnType) {
result.add(method);
}
}
}
return result;
}
public static Iterable fieldsOfType(Class> objClass, final Class> fieldClass, final boolean strict){
final Field[] fields = getClassDesc(objClass).fields;
return new FluentIterable() {
@Override
public Iterator iterator() {
return new AbstractIterator() {
int i = 0;
final int l = fields.length;
@Override
protected Field computeNext() {
for(;i fieldNames(Class> aClass){
return projectMethod(fields(aClass), Field.class, String.class, "getName");
}
public static List fields(Class> aClass) {
return asList(getClassDesc(aClass).fields);
}
public static List methodNames(Class> aClass){
return projectMethod(methods(aClass), MethodDesc.class, String.class, "getName");
}
public static List methods(Class> aClass) {
return asList(getClassDesc(aClass).methods);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy