/src/g6/db/FastMapper.java
https://bitbucket.org/yangibaev/g6 · Java · 188 lines · 157 code · 31 blank · 0 comment · 38 complexity · 94d7d08b19208611c7609eb88029bcd8 MD5 · raw file
- package g6.db;
-
- import java.beans.BeanInfo;
- import java.beans.Introspector;
- import java.beans.PropertyDescriptor;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.lang.reflect.ParameterizedType;
- import java.lang.reflect.Type;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.concurrent.ConcurrentHashMap;
-
- import com.mongodb.BasicDBList;
- import com.mongodb.BasicDBObject;
- import net.sf.cglib.reflect.FastClass;
-
- import com.mongodb.DBObject;
- import org.bson.types.ObjectId;
-
- public class FastMapper implements IMapper {
-
- private ConcurrentHashMap<Class, FastBean> _cache = new ConcurrentHashMap<Class, FastBean>();
-
- private FastBean getFastBeanForClass(Class clazz) {
- FastBean result = _cache.get(clazz);
- if (result == null) {
- try {
-
- String idFieldName = null;
- for (Field field : clazz.getDeclaredFields()) {
- if (field.isAnnotationPresent(Id.class)) {
- idFieldName = field.getName();
- if (idFieldName.indexOf("_") == 0) {
- idFieldName = idFieldName.substring(1);
- }
- break;
- }
- }
-
-
- FastClass fastClass = FastClass.create(clazz);
- BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
-
- PropertyDescriptor[] propertyDescriptors = beanInfo
- .getPropertyDescriptors();
-
- ArrayList<FieldAccessor> writeAccessors = new ArrayList<FieldAccessor>();
- ArrayList<FieldAccessor> readAccessors = new ArrayList<FieldAccessor>();
-
- for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
- if (isPersistent(propertyDescriptor)) {
-
- String propertyName = propertyDescriptor.getName();
- boolean isIdField = propertyName.equals(idFieldName);
-
- Type genericParamType = null;
- Type genericType = propertyDescriptor.getReadMethod().getGenericReturnType();
- if (genericType instanceof ParameterizedType) {
- genericParamType = ((ParameterizedType) genericType).getActualTypeArguments()[0];
- if (isBuiltinType(genericParamType)) {
- genericParamType = null;
- }
- }
-
- Method writeMethod = propertyDescriptor
- .getWriteMethod();
- Class<?> propertyType = propertyDescriptor.getPropertyType();
- boolean isBuiltinType = isBuiltinType(propertyType);
-
- writeAccessors.add(new FieldAccessor(fastClass
- .getMethod(writeMethod), propertyName, propertyType, genericParamType, isBuiltinType, isIdField));
-
- Method readMethod = propertyDescriptor.getReadMethod();
- readAccessors.add(new FieldAccessor(fastClass
- .getMethod(readMethod), propertyName, propertyType, genericParamType, isBuiltinType, isIdField));
- }
- }
-
- result = new FastBean(
- readAccessors.toArray(new FieldAccessor[]{}),
- writeAccessors.toArray(new FieldAccessor[]{}));
- _cache.put(clazz, result);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- return result;
- }
-
- private boolean isPersistent(PropertyDescriptor propertyDescriptor) {
- return !propertyDescriptor.getName().equals("class")
- && propertyDescriptor.getWriteMethod() != null;
- }
-
- private boolean isBuiltinType(Type type) {
- return type.equals(String.class) ||
- type.equals(Long.class) ||
- type.equals(Integer.class) ||
- type.equals(Byte.class) ||
- type.equals(Short.class) ||
- type.equals(Float.class) ||
- type.equals(Double.class) ||
- type.equals(Character.class) ||
- type.equals(Boolean.class)||
- type.equals(DBObject.class)||
- type.equals(ObjectId.class);
- }
-
- @Override
- public void toPojo(DBObject dbObject, Object object) {
- try {
- Object valueFromDB = null;
- for (FieldAccessor fieldAccesor : getFastBeanForClass(object
- .getClass()).writeAccessors) {
-
- if (fieldAccesor.isIdField) {
- valueFromDB = dbObject.get("_id");
- } else {
- valueFromDB = dbObject.get(fieldAccesor.name);
-
- if (valueFromDB != null) {
- if (valueFromDB instanceof List && fieldAccesor.genericType != null) {
- List dbList = (BasicDBList) dbObject.get(fieldAccesor.name);
- ArrayList pojoList = new ArrayList();
- for (Object item : dbList) {
- Object pojoItem = ((Class) fieldAccesor.genericType).newInstance();
- toPojo((DBObject) item, pojoItem);
-
- pojoList.add(pojoItem);
- }
- valueFromDB = pojoList;
- } else if (!fieldAccesor.isBuiltinType && !(valueFromDB instanceof List)) {
- Object nestedPojo = fieldAccesor.fieldType.newInstance();
- toPojo((DBObject) valueFromDB, nestedPojo);
- valueFromDB = nestedPojo;
- }
-
- }
- }
- fieldAccesor.method.invoke(object, new Object[]{valueFromDB});
- }
-
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void fromPojo(Object object, DBObject dbObject) {
- try {
- for (FieldAccessor fieldAccesor : getFastBeanForClass(object
- .getClass()).readAccessors) {
- Object fieldValue = fieldAccesor.method.invoke(object, null);
- if (fieldValue != null) {
- if (fieldAccesor.isIdField) {
- dbObject.put("_id", fieldValue);
- } else {
- if (fieldValue instanceof List && fieldAccesor.genericType != null) {
- ArrayList sourceList = (ArrayList) fieldValue;
- BasicDBList dbList = new BasicDBList();
-
- for (Object item : sourceList) {
-
- DBObject dbItem = new BasicDBObject();
- fromPojo(item, dbItem);
- dbList.add(dbItem);
- }
-
- dbObject.put(fieldAccesor.name, dbList);
- } else if (!fieldAccesor.isBuiltinType && !(fieldValue instanceof List)) {
- DBObject dbObject2 = new BasicDBObject();
- fromPojo(fieldValue, dbObject2);
- dbObject.put(fieldAccesor.name, dbObject2);
- } else {
- dbObject.put(fieldAccesor.name, fieldValue);
- }
- }
- } else {
- dbObject.put(fieldAccesor.name, null);
- }
- }
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- }