package com.android.pc.ioc.db.sqlite; import android.database.Cursor; import com.android.pc.ioc.app.Ioc; import com.android.pc.ioc.db.table.Column; import com.android.pc.ioc.db.table.DbModel; import com.android.pc.ioc.db.table.Finder; import com.android.pc.ioc.db.table.Foreign; import com.android.pc.ioc.db.table.Table; public class CursorUtils { public static <T> T getEntity(DbUtils db, Cursor cursor, Class<T> entityType, long findCacheSequence) { if (db == null || cursor == null) return null; EntityTempCache.setSeq(findCacheSequence); try { Table table = Table.get(entityType); int idIndex = cursor.getColumnIndex(table.getId().getColumnName()); String idStr = cursor.getString(idIndex); T entity = EntityTempCache.get(entityType, idStr); if (entity == null) { entity = entityType.newInstance(); EntityTempCache.put(entity, idStr); } else { return entity; } int columnCount = cursor.getColumnCount(); for (int i = 0; i < columnCount; i++) { String columnName = cursor.getColumnName(i); Column column = table.columnMap.get(columnName); if (column != null) { if (column instanceof Foreign) { Foreign foreign = (Foreign) column; if (foreign.getFieldValue(entity) == null) { foreign.db = db; foreign.setValue2Entity(entity, cursor.getString(i)); } } else { column.setValue2Entity(entity, cursor.getString(i)); } } else if (columnName.equals(table.getId().getColumnName())) { table.getId().setValue2Entity(entity, cursor.getString(i)); } } for (Column column : table.columnMap.values()) { if (column instanceof Finder) { Finder finder = (Finder) column; if (finder.getFieldValue(entity) == null) { finder.db = db; finder.setValue2Entity(entity, null); } } } return entity; } catch (Exception e) { Ioc.getIoc().getLogger().e(e); } return null; } public static DbModel getDbModel(Cursor cursor) { DbModel result = null; if (cursor != null) { result = new DbModel(); int columnCount = cursor.getColumnCount(); for (int i = 0; i < columnCount; i++) { result.add(cursor.getColumnName(i), cursor.getString(i)); } } return result; } public static class FindCacheSequence { private static long seq = 0; private static final String FOREIGN_LAZY_LOADER_CLASS_NAME = ForeignLazyLoader.class.getName(); private static final String FINDER_LAZY_LOADER_CLASS_NAME = FinderLazyLoader.class.getName(); public static long getSeq() { String findMethodCaller = Thread.currentThread().getStackTrace()[4].getClassName(); if (!findMethodCaller.equals(FOREIGN_LAZY_LOADER_CLASS_NAME) && !findMethodCaller.equals(FINDER_LAZY_LOADER_CLASS_NAME)) { ++seq; } return seq; } } private static class EntityTempCache { private EntityTempCache() { } /** * k1: entityType; * k2: idValue * value: entity */ private static final DoubleKeyValueMap<Class, String, Object> cache = new DoubleKeyValueMap<Class, String, Object>(); private static long seq = 0; public static void put(Object entity, String idStr) { cache.put(entity.getClass(), idStr, entity); } @SuppressWarnings("unchecked") public static <T> T get(Class<T> entityType, String idStr) { return (T) cache.get(entityType, idStr); } public static void setSeq(long seq) { if (EntityTempCache.seq != seq) { cache.clear(); EntityTempCache.seq = seq; } } } }