All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.droidparts.persist.sql.EntityManager Maven / Gradle / Ivy

There is a newer version: 3.2.5
Show newest version
/**
 * 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