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

com.j256.ormlite.table.TableInfo Maven / Gradle / Ivy

package com.j256.ormlite.table;

import java.lang.reflect.Constructor;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import com.j256.ormlite.db.DatabaseType;
import com.j256.ormlite.field.FieldType;
import com.j256.ormlite.misc.SqlExceptionUtil;

/**
 * Information about a database table including the associated tableName, class, constructor, and the included fields.
 * 
 * @param T
 *            The class that the code will be operating on.
 * @author graywatson
 */
public class TableInfo {

	private final Class dataClass;
	private final String tableName;
	private final FieldType[] fieldTypes;
	private final Map fieldNameMap = new HashMap();
	private final FieldType idField;
	private final Constructor constructor;

	/**
	 * Creates a holder of information about a table/class.
	 * 
	 * @param databaseType
	 *            Database type we are storing the class in.
	 * @param dataClass
	 *            Class that we are holding information about.
	 */
	public TableInfo(DatabaseType databaseType, Class dataClass) {
		this(databaseType, DatabaseTableConfig.fromClass(databaseType, dataClass));
	}

	/**
	 * Creates a holder of information about a table/class.
	 * 
	 * @param databaseType
	 *            Database type we are storing the class in.
	 * @param tableConfig
	 *            Configuration for our table.
	 */
	public TableInfo(DatabaseType databaseType, DatabaseTableConfig tableConfig) {
		this.dataClass = tableConfig.getDataClass();
		this.tableName = tableConfig.getTableName();
		this.fieldTypes = tableConfig.extractFieldTypes(databaseType);
		// find the id field
		FieldType findIdFieldType = null;
		for (FieldType fieldType : fieldTypes) {
			if (fieldType.isId()) {
				if (findIdFieldType != null) {
					throw new IllegalArgumentException("More than 1 idField configured for class " + dataClass + " ("
							+ findIdFieldType + "," + fieldType + ")");
				}
				findIdFieldType = fieldType;
			}
			fieldNameMap.put(fieldType.getDbColumnName(), fieldType);
		}
		// if we just have 1 field and it is a generated-id then inserts will be blank which is not allowed.
		if (fieldTypes.length == 1 && findIdFieldType != null && findIdFieldType.isGeneratedId()) {
			throw new IllegalArgumentException("Must have more than a single field which is a generated-id for class "
					+ dataClass);
		}
		// can be null if there is no id field
		this.idField = findIdFieldType;
		this.constructor = findNoArgConstructor(dataClass);
	}

	/**
	 * Return the class associated with this object-info.
	 */
	public Class getDataClass() {
		return dataClass;
	}

	/**
	 * Return the name of the table associated with the object.
	 */
	public String getTableName() {
		return tableName;
	}

	/**
	 * Return the array of field types associated with the object.
	 */
	public FieldType[] getFieldTypes() {
		return fieldTypes;
	}

	/**
	 * Return the {@link FieldType} associated with the columnName.
	 */
	public FieldType nameToFieldType(String columnName) {
		return fieldNameMap.get(columnName);
	}

	/**
	 * Return the id-field associated with the object.
	 */
	public FieldType getIdField() {
		return idField;
	}

	/**
	 * Return a string representation of the object.
	 */
	public String objectToString(T object) {
		StringBuilder sb = new StringBuilder();
		sb.append(object.getClass().getSimpleName());
		for (FieldType fieldType : fieldTypes) {
			sb.append(' ').append(fieldType.getDbColumnName()).append("=");
			try {
				sb.append(fieldType.getConvertedFieldValue(object));
			} catch (Exception e) {
				throw new IllegalStateException("Could not generate toString of field " + fieldType, e);
			}
		}
		return sb.toString();
	}

	/**
	 * Create and return an object of this type using our reflection constructor.
	 */
	public T createObject() throws SQLException {
		boolean accessible = constructor.isAccessible();
		try {
			if (!accessible) {
				constructor.setAccessible(true);
			}
			// create our instance
			return constructor.newInstance();
		} catch (Exception e) {
			throw SqlExceptionUtil.create("Could not create object for " + dataClass, e);
		} finally {
			if (!accessible) {
				constructor.setAccessible(false);
			}
		}
	}

	private Constructor findNoArgConstructor(Class dataClass) {
		Constructor[] constructors;
		try {
			@SuppressWarnings("unchecked")
			Constructor[] consts = (Constructor[]) dataClass.getDeclaredConstructors();
			// i do this [grossness] to be able to move the Suppress inside the method
			constructors = consts;
		} catch (Exception e) {
			throw new IllegalArgumentException("Can't lookup declared constructors for " + dataClass, e);
		}
		for (Constructor con : constructors) {
			if (con.getParameterTypes().length == 0) {
				return con;
			}
		}
		throw new IllegalArgumentException("Can't find a no-arg constructor for " + dataClass);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy