/* * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lidroid.xutils.db.sqlite; import android.database.Cursor; import com.lidroid.xutils.DbUtils; import com.lidroid.xutils.db.table.*; import com.lidroid.xutils.util.LogUtils; import java.util.concurrent.ConcurrentHashMap; public class CursorUtils { @SuppressWarnings("unchecked") public static <T> T getEntity(final DbUtils db, final Cursor cursor, Class<T> entityType, long findCacheSequence) { if (db == null || cursor == null) return null; EntityTempCache.setSeq(findCacheSequence); try { Table table = Table.get(db, entityType); Id id = table.id; String idColumnName = id.getColumnName(); int idIndex = id.getIndex(); if (idIndex < 0) { idIndex = cursor.getColumnIndex(idColumnName); } Object idValue = id.getColumnConverter().getFieldValue(cursor, idIndex); T entity = EntityTempCache.get(entityType, idValue); if (entity == null) { entity = entityType.newInstance(); id.setValue2Entity(entity, cursor, idIndex); EntityTempCache.put(entityType, idValue, entity); } 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) { column.setValue2Entity(entity, cursor, i); } } // init finder for (Finder finder : table.finderMap.values()) { finder.setValue2Entity(entity, null, 0); } return entity; } catch (Throwable e) { LogUtils.e(e.getMessage(), e); } return null; } public static DbModel getDbModel(final 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 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() { } private static final ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<String, Object>(); private static long seq = 0; public static <T> void put(Class<T> entityType, Object idValue, Object entity) { cache.put(entityType.getName() + "#" + idValue, entity); } @SuppressWarnings("unchecked") public static <T> T get(Class<T> entityType, Object idValue) { return (T) cache.get(entityType.getName() + "#" + idValue); } public static void setSeq(long seq) { if (EntityTempCache.seq != seq) { cache.clear(); EntityTempCache.seq = seq; } } } }