
org.droidparts.persist.sql.EntityManager Maven / Gradle / Ivy
/**
* Copyright 2013 Alex Yanchenko
*
* 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 org.droidparts.persist.sql;
import static java.util.Arrays.asList;
import static org.droidparts.inner.FieldSpecRegistry.getTableColumnSpecs;
import static org.droidparts.inner.ReflectionUtils.getFieldVal;
import static org.droidparts.inner.ReflectionUtils.newInstance;
import static org.droidparts.inner.ReflectionUtils.setFieldVal;
import static org.droidparts.inner.TypeHelper.isArray;
import static org.droidparts.inner.TypeHelper.isCollection;
import static org.droidparts.inner.TypeHelper.isEntity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import org.droidparts.Injector;
import org.droidparts.annotation.inject.InjectDependency;
import org.droidparts.inner.FieldSpecRegistry;
import org.droidparts.inner.TypeHandlerRegistry;
import org.droidparts.inner.ann.FieldSpec;
import org.droidparts.inner.ann.sql.ColumnAnn;
import org.droidparts.inner.handler.TypeHandler;
import org.droidparts.model.Entity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class EntityManager extends
AbstractEntityManager {
@InjectDependency
private SQLiteDatabase db;
private final Class cls;
private final Context ctx;
public EntityManager(Class cls, Context ctx) {
this.cls = cls;
this.ctx = ctx.getApplicationContext();
Injector.get().inject(ctx, this);
}
protected EntityManager(Class cls, Context ctx,
SQLiteDatabase db) {
this.cls = cls;
this.ctx = ctx;
this.db = db;
}
public Context getContext() {
return ctx;
}
@Override
public EntityType readRow(Cursor cursor) {
EntityType entity = newInstance(cls);
for (FieldSpec spec : getTableColumnSpecs(cls)) {
int colIdx = cursor.getColumnIndex(spec.ann.name);
if (colIdx >= 0) {
Object columnVal = readFromCursor(cursor, colIdx,
spec.field.getType(), spec.componentType);
if (columnVal != null || spec.ann.nullable) {
setFieldVal(entity, spec.field, columnVal);
}
}
}
return entity;
}
@Override
public void fillForeignKeys(EntityType item, String... columnNames) {
HashSet columnNameSet = new HashSet(asList(columnNames));
boolean fillAll = columnNameSet.isEmpty();
for (FieldSpec spec : getTableColumnSpecs(cls)) {
if (fillAll || columnNameSet.contains(spec.ann.name)) {
Class> fieldType = spec.field.getType();
if (isEntity(fieldType)) {
Entity foreignEntity = getFieldVal(item, spec.field);
if (foreignEntity != null) {
EntityManager manager = subManager(spec.field
.getType());
Object obj = manager.read(foreignEntity.id);
setFieldVal(item, spec.field, obj);
}
} else if ((isArray(fieldType) || isCollection(fieldType))
&& isEntity(spec.componentType)) {
EntityManager manager = subManager(spec.componentType);
if (isArray(fieldType)) {
Entity[] arr = getFieldVal(item, spec.field);
if (arr != null) {
for (int i = 0; i < arr.length; i++) {
Entity ent = arr[i];
if (ent != null) {
arr[i] = manager.read(ent.id);
}
}
}
} else {
Collection coll = getFieldVal(item, spec.field);
if (coll != null) {
ArrayList entities = new ArrayList(
coll.size());
for (Entity ent : coll) {
if (ent != null) {
entities.add(manager.read(ent.id));
}
}
coll.clear();
coll.addAll(entities);
}
}
}
}
}
}
@Override
protected SQLiteDatabase getDB() {
return db;
}
@Override
protected String getTableName() {
return FieldSpecRegistry.getTableName(cls);
}
@Override
protected ContentValues toContentValues(EntityType item) {
ContentValues cv = new ContentValues();
for (FieldSpec spec : getTableColumnSpecs(cls)) {
Object columnVal = getFieldVal(item, spec.field);
putToContentValues(cv, spec.ann.name, spec.field.getType(),
spec.componentType, columnVal);
}
return cv;
}
@Override
protected void createForeignKeys(EntityType item) {
for (FieldSpec spec : getTableColumnSpecs(cls)) {
Class> fieldType = spec.field.getType();
if (isEntity(fieldType)) {
Entity foreignEntity = getFieldVal(item, spec.field);
if (foreignEntity != null && foreignEntity.id == 0) {
subManager(spec.field.getType()).create(foreignEntity);
}
} else if ((isArray(fieldType) || isCollection(fieldType))
&& isEntity(spec.componentType)) {
ArrayList toCreate = new ArrayList();
if (isArray(fieldType)) {
Entity[] arr = getFieldVal(item, spec.field);
if (arr != null) {
for (Entity ent : arr) {
if (ent != null && ent.id == 0) {
toCreate.add(ent);
}
}
}
} else {
Collection coll = getFieldVal(item, spec.field);
if (coll != null) {
for (Entity ent : coll) {
if (ent != null && ent.id == 0) {
toCreate.add(ent);
}
}
}
}
if (!toCreate.isEmpty()) {
subManager(spec.componentType).create(toCreate);
}
}
}
}
@Override
protected void fillEagerForeignKeys(EntityType item) {
String[] eagerColumnNames = getEagerForeignKeyColumnNames();
if (eagerColumnNames.length != 0) {
fillForeignKeys(item, eagerColumnNames);
}
}
protected String[] getEagerForeignKeyColumnNames() {
if (eagerForeignKeyColumnNames == null) {
HashSet eagerColumnNames = new HashSet();
for (FieldSpec spec : getTableColumnSpecs(cls)) {
if (spec.ann.eager) {
eagerColumnNames.add(spec.ann.name);
}
}
eagerForeignKeyColumnNames = eagerColumnNames
.toArray(new String[eagerColumnNames.size()]);
}
return eagerForeignKeyColumnNames;
}
private String[] eagerForeignKeyColumnNames;
@SuppressWarnings("unchecked")
protected void putToContentValues(ContentValues cv, String key,
Class valueType, Class componentType, Object value)
throws IllegalArgumentException {
if (value == null) {
cv.putNull(key);
} else {
TypeHandler handler = TypeHandlerRegistry.getHandler(valueType);
handler.putToContentValues(valueType, componentType, cv, key,
(T) value);
}
}
protected Object readFromCursor(Cursor cursor, int columnIndex,
Class valType, Class componentType)
throws IllegalArgumentException {
if (cursor.isNull(columnIndex)) {
return null;
} else {
TypeHandler handler = TypeHandlerRegistry.getHandler(valType);
return handler.readFromCursor(valType, componentType, cursor,
columnIndex);
}
}
@SuppressWarnings("unchecked")
private EntityManager subManager(Class> entityType) {
return new EntityManager((Class) entityType, ctx, db);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy