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

org.mentabean.BeanConfig Maven / Gradle / Ivy

There is a newer version: 2.2.4
Show newest version
/*
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 * 
 * MentaBean => http://www.mentabean.org
 * Author: Sergio Oliveira Jr. ([email protected])
 */
package org.mentabean;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import org.mentabean.type.AutoIncrementType;
import org.mentabean.type.SequenceType;

/**
 * A class representing a bean configuration, like table name, primary keys and fields in the database.
 * 
 * @author [email protected]
 */
public class BeanConfig {

	private final Map fieldList = new LinkedHashMap();

	private final Map pkList = new LinkedHashMap();
	
	private final Class beanClass;

	private final String tableName;

	private DBField sequence = null;
	
	private String sequenceName = null;

	private DBField autoincrement = null;

	/**
	 * Creates a configuration for a bean represented by the given class.
	 * 
	 * @param beanClass
	 *            The bean klass
	 * @param tableName
	 *            The database table where the bean properties will be stored.
	 */
	public BeanConfig(final Class beanClass, final String tableName) {

		this.beanClass = beanClass;

		this.tableName = tableName;
	}

	/**
	 * Return the table name where the bean properties are stored.
	 * 
	 * @return The database table name.
	 */
	public String getTableName() {

		return tableName;
	}

	/**
	 * Return the bean class.
	 * 
	 * @return The bean class.
	 */
	public Class getBeanClass() {

		return beanClass;
	}

	private DBField findDBField(final String name) {

		return fieldList.get(name);
	}
	
	/**
	 * Add the sequence name *in the database* that will be used for this field.
	 * 
	 * NOTE: A field of type SEQUENCE must have been defined before or an IllegalStateException is thrown.
	 * 
	 * @param seqNameInDb the name of the sequence in the database
	 * @return this bean config
	 */
	public BeanConfig addSequenceName(String seqNameInDb) {
		
		if (sequence == null) {
			throw new IllegalStateException("There is no sequence field defined!");
		}
		
		sequenceName = seqNameInDb;
		return this;
	}
	
	/**
	 * Alias for method addSequence
	 * 
	 * @param seqNameInDb
	 * @return this bean config
	 */
	public BeanConfig seq(String seqNameInDb) {
		return addSequenceName(seqNameInDb);
	}

	/**
	 * Returns the name of the sequence in the database.
	 * 
	 * NOTE: The name returned is the name of the sequence in the database.
	 * 
	 * @return the name of the sequence in the database.
	 */
	public String getSequenceName() {
		return sequenceName;
	}
	
	private BeanConfig addField(final String name, final String dbName, final DBType type, final boolean isPK) {

		if (!isPK) {

			if (type instanceof SequenceType) {
				throw new IllegalStateException("A sequence type can only be a primary key!");
			}

			if (type instanceof AutoIncrementType) {
				throw new IllegalStateException("A auto-increment type can only be a primary key!");
			}
		}

		final DBField f = new DBField(name, dbName, type, isPK);

		fieldList.remove(name); // just in case we are re-adding it...

		fieldList.put(name, f);

		if (isPK) {

			pkList.remove(name); // just in case we are re-adding it...

			pkList.put(name, f);

			if (type instanceof SequenceType) {

				if (sequence != null) {
					throw new IllegalStateException("A bean can have only one sequence field!");
				}

				sequence = f;

			} else if (type instanceof AutoIncrementType) {

				if (autoincrement != null) {
					throw new IllegalStateException("A bean can have only one auto-increment field!");
				}

				autoincrement = f;
			}
		}

		return this;
	}

	/**
	 * Return an auto-increment field, if one was configured for this bean.
	 * 
	 * Note: A bean can have only one auto-increment field configured for this bean. Attempting to configure more than one will throw an exception.
	 * 
	 * @return the auto-increment field configured for this bean or null if it was not defined
	 */
	public DBField getAutoIncrementField() {

		return autoincrement;
	}

	/**
	 * Return a sequence field, if one was configured for this bean.
	 * 
	 * Note: A bean can have only one sequence field configured for this bean. Attempting to configure more than one will throw an exception.
	 * 
	 * @return the sequence field configured for this bean or null if it was not defined
	 */
	public DBField getSequenceField() {

		return sequence;
	}

	/**
	 * Add a database field for the given property with the given database type. It assumes that the property name is the SAME as the database column name. If they are different, use the other addField method.
	 * 
	 * @param name
	 *            The bean property name (same as the database column name)
	 * @param type
	 *            The database type
	 * @return This BeanConfig (Fluent API)
	 */
	public BeanConfig field(final String name, final DBType type) {

		return addField(name, name, type, false);
	}

	/**
	 * Add a database field for the given property with the given database type.
	 * 
	 * @param name
	 *            The bean property name
	 * @param dbName
	 *            The name of the database column holding this property
	 * @param type
	 *            The database type
	 * @return This BeanConfig (Fluent API)
	 */
	public BeanConfig field(final String name, final String dbName, final DBType type) {

		return addField(name, dbName, type, false);
	}

	/**
	 * Add a bean property that is the primary key in the database. The column name is the same as the property bean name. If they are different use the other pk method. All beans must have a primary key and you can call this method multiple times to support composite primary keys.
	 * 
	 * @param name
	 *            The bean property name
	 * @param type
	 *            The database type
	 * @return This BeanConfig (Fluent API)
	 */
	public BeanConfig pk(final String name, final DBType type) {

		return addField(name, name, type, true);
	}

	/**
	 * Add a property that is the primary key in the database. All beans must have a primary key and you can call this method multiple times to support composite primary keys.
	 * 
	 * @param name
	 *            The bean property name
	 * @param dbName
	 *            The name of the database column holding this property
	 * @param type
	 *            The database type
	 * @return This BeanConfig (Fluent API)
	 */
	public BeanConfig pk(final String name, final String dbName, final DBType type) {

		return addField(name, dbName, type, true);
	}

	/**
	 * Return the number of fields configured for this bean. It includes the PK.
	 * 
	 * @return The number of fields configured for this bean.
	 */
	public int getNumberOfFields() {

		return fieldList.size();
	}

	public int getNumberOfPKs() {

		return pkList.size();
	}

	@Override
	public String toString() {

		final StringBuilder sb = new StringBuilder(64);

		sb.append("BeanConfig: ").append(beanClass.getName()).append(" tableName=").append(tableName);

		return sb.toString();
	}

	/**
	 * Return all DBFields configured for this bean. It includes the PK as well.
	 * 
	 * @return An Iterator with all DBFields configured for this bean.
	 */
	public Iterator fields() {

		return fieldList.values().iterator();
	}

	/**
	 * Check whether the primary key was defined.
	 * 
	 * @return true if a primary key was defined.
	 */
	public boolean hasPK() {

		return !pkList.isEmpty();
	}

	/**
	 * Return an iterator with the DBFields for the PK configured for this bean.
	 * 
	 * Note: A bean can have more than one property as its primary key, in that case it has a composite primary key.
	 * 
	 * @return An iterator with the DBFields for the PK.
	 */
	public Iterator pks() {

		return pkList.values().iterator();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy