/*******************************************************************************
 * Copyright (c) 2007, 2010 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.jpa.gen.internal;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jpt.common.utility.JavaType;
import org.eclipse.jpt.jpa.db.Column;
import org.eclipse.jpt.jpa.db.Table;
import org.eclipse.jpt.jpa.gen.internal.util.DTPUtil;
import org.eclipse.jpt.jpa.gen.internal.util.EntityGenTools;
import org.eclipse.jpt.jpa.gen.internal.util.StringUtil;

/**
 * Represents the ORM generation properties for a database table.
 * 
 * <p>
 * This is designed to be created/changed by the generation wizard, and
 * generated using Velocity templates. The modified properties (if any) are
 * persisted/retrieved using <code>ORMGenCustomizer</code>.
 * 
 */
public class ORMGenTable
{
	private ORMGenCustomizer mCustomizer;
	private List<ORMGenColumn> mColumns;
	private Table mDbTable;
	private HashMap<String, String> columnTypesMap =  null;
	/**
	 * @param table
	 *            The database table or null if this table is used to get/set
	 *            the default table properties (properties that apply to all
	 *            tables unless overriden).
	 */
	public ORMGenTable(Table table, ORMGenCustomizer customizer) {
		super();
		mDbTable = table;
		mCustomizer = customizer;
	}

	public ORMGenCustomizer getCustomizer() {
		return mCustomizer;
	}

	/**
	 * Returns true if this table is is used to get/set the default table
	 * properties.
	 */
	public boolean isDefaultsTable() {
		return mDbTable == null;
	}

	protected String customized(String propName) {
		return getCustomizer().getProperty(propName, getName(), null);
	}

	protected boolean customizedBoolean(String propName) {
		return getCustomizer().getBooleanProperty(propName, getName(), null);
	}

	protected void setCustomized(String propName, String value) {
		if (value != null && value.length() == 0) {
			value = null;
		}
		getCustomizer().setProperty(propName, value, getName(), null);
	}

	protected void setCustomizedBoolean(String propName, boolean value, boolean defaultValue) {
		if (defaultValue == value) {
			setCustomized(propName, null); // remove the property
		}
		else {
			getCustomizer().setBooleanProperty(propName, value, getName(), null);
		}
	}

	public Table getDbTable() {
		return mDbTable;
	}

	/**
	 * Returns the table name.
	 */
	public String getName() {
		if (mDbTable == null)
			return ORMGenCustomizer.ANY_TABLE;
		return mDbTable.getName();
	}

	public String getJoinTableAnnotationName() {
		if (mDbTable == null)
			return ORMGenCustomizer.ANY_TABLE;
		String annotationName = this.mCustomizer.getDatabaseAnnotationNameBuilder().buildJoinTableAnnotationName(mDbTable);
		return annotationName != null ? annotationName : mDbTable.getName();
	}

	/**
	 * Returns the database schema containing the table.
	 */
	public String getSchema() {
		if (DTPUtil.isDefaultSchema(mDbTable) || mDbTable.getSchema()==null)
			return ""; //$NON-NLS-1$
		String schemaName = mDbTable.getSchema().getName();
		return schemaName;
	}

	public void setSourceFolder(String srcFolder){
		setCustomized(SRC_FOLDER, srcFolder);
	}
	
	public String getSourceFolder(){
		String srcFolder = customized(SRC_FOLDER);
		return srcFolder == null ? "" : srcFolder;
	}
	
	public String getImportStatements(){
		buildColumnTypesMap();
		Collection<String> packages = columnTypesMap.keySet();
		StringBuilder ret = new StringBuilder();
		for ( String s : packages ) {
			ret.append( "import " + s + ";\n"); //$NON-NLS-1$
		}

		List<AssociationRole> associationRoles = getAssociationRoles();
		for ( AssociationRole role :  associationRoles ) {
			if ( role.getCardinality().equals( Association.ONE_TO_MANY )
					|| role.getCardinality().equals( Association.MANY_TO_MANY ) ) {
				ret.append( "import " + getDefaultCollectionType() + ";\n"); //$NON-NLS-1$
				break;
			}
		}
		
		return ret.toString();
	}
	
	/**
	 * Construct import statements for types from javax.persistence package
	 * @return
	 */
	private String getJavaxPersistenceImportStatements() {
		StringBuilder ret = new StringBuilder();
		ret.append( "import javax.persistence.Entity;\n"); //$NON-NLS-1$
		//TODO: only if @Columns is needed
		ret.append( "import javax.persistence.Column;\n");//$NON-NLS-1$
		//TODO: only if there is @Id
		ret.append( "import javax.persistence.Id;\n");//$NON-NLS-1$
		if( !this.isDefaultname() )
			ret.append( "import javax.persistence.Table;\n");//$NON-NLS-1$
		if( this.isCompositeKey() )
			ret.append( "import javax.persistence.EmbeddedId;\n"); //$NON-NLS-1$
		// append javax.persistence package imports
		HashSet<String> jpaImports = new HashSet<String>(); 
		List<AssociationRole> associationRoles = getAssociationRoles();
		for( AssociationRole role :  associationRoles ){
			if( role.getCardinality().equals( Association.ONE_TO_ONE ) ){
				jpaImports.add( "import javax.persistence.OneToOne;" );//$NON-NLS-1$
			}else{
				if( role.getCardinality().equals( Association.ONE_TO_MANY ) ){
					jpaImports.add( "import javax.persistence.OneToMany;\n" );//$NON-NLS-1$
				}else if( role.getCardinality().equals( Association.MANY_TO_ONE ) ){
					jpaImports.add( "import javax.persistence.ManyToOne;\n" );//$NON-NLS-1$
					jpaImports.add( "import javax.persistence.JoinColumn;\n" ); //$NON-NLS-1$
				}else if( role.getCardinality().equals( Association.MANY_TO_MANY ) ){
					jpaImports.add( "import javax.persistence.ManyToMany;\n" );//$NON-NLS-1$
					jpaImports.add( "import javax.persistence.JoinTable;\n" );//$NON-NLS-1$
					jpaImports.add( "import javax.persistence.JoinColumns;\n");//$NON-NLS-1$
					jpaImports.add( "import javax.persistence.JoinColumn;\n" );//$NON-NLS-1$
				}
			}
		}
		for( String s: jpaImports){
			ret.append(s);
		}
		return ret.toString();
	}

	public HashMap<String, String> buildColumnTypesMap(){
		if ( columnTypesMap != null) {
			return columnTypesMap;
		}
		columnTypesMap = new HashMap<String, String>();
		for ( ORMGenColumn col : this.getColumns() ) {
			String type = col.getPropertyType();
			if ( !col.isPartOfCompositePrimaryKey()
					&& !col.isForeignKey()
					&& !type.startsWith("java.lang") && type.indexOf('.')>0 ) {
				String simpleType= type.substring( type.lastIndexOf('.')+1 );
				columnTypesMap.put(type, simpleType);
			}
		}
		return columnTypesMap;
	}
	
	public String getSimplifiedColType(String fqtn ) {
		HashMap<String, String> map = buildColumnTypesMap();
		String typeName = map.get(fqtn);
		if (  typeName != null ) {
			return typeName;
		}
		return fqtn;
	}
	
	/**
	 * Sets the package for the generated class (empty string for the default
	 * package)
	 */
	public void setPackage(String pkg) {
		getCustomizer().setProperty(PACKAGE, pkg, getName(), null); 
		// not calling setCustomized so that empty strings do not get nulled out.
	}

	/**
	 * Returns the Java package (empty string for the default package).
	 */
	public String getPackage() {
		String packageName = customized(PACKAGE);
		return packageName == null ? "" : packageName; //$NON-NLS-1$
	}

	/**
	 * Returns the generated Java class name (not qualified).
	 */
	public String getClassName() {
		String name = customized(CLASS_NAME);
		if (name == null) {
			// name = StringUtil.tableNameToVarName(getName());
			// name = StringUtil.initUpper(name);
			name = EntityGenTools.convertToUniqueJavaStyleClassName(getName(), new ArrayList<String>());
			name = StringUtil.singularise(name);
		}
		return name;
	}

	public void setClassName(String className) {
		/*
		 * if the class name is the same as the (possibly computed) class name
		 * then nothing to do
		 */
		if (!StringUtil.equalObjects(className, getClassName())) {
			setCustomized(CLASS_NAME, className);
		}
	}

	/**
	 * Returns a name suitable to be used as a variable or class name. This is
	 * computed based on the table name.
	 * 
	 * @param singular
	 *            Whether the name should be singular or plural.
	 */
	public String getVarName(boolean singular) {
		String name = StringUtil.tableNameToVarName(getName());
		if (singular) {
			name = StringUtil.singularise(name);
		}
		else {
			name = StringUtil.pluralise(name);
		}
		return name;
	}

	/**
	 * Returns the fully qualified generated Java class name.
	 */
	public String getQualifiedClassName() {
		return qualify(getClassName());
	}

	/**
	 * Returns the composite key Java class name (not qualified).
	 */
	public String getCompositeKeyClassName() {
		String name = customized(COMPOSITE_KEY_CLASS_NAME);
		if (name == null) {
			name = getClassName() + "PK"; //$NON-NLS-1$
		}
		return name;
	}

	/**
	 * Returns the fully qualified composite key Java class name.
	 */
	public String getQualifiedCompositeKeyClassName() {
		return qualify(getCompositeKeyClassName());
	}

	/**
	 * Returns the composite key property name.
	 */
	public String getCompositeKeyPropertyName() {
		return "id"; //$NON-NLS-1$
	}

	/**
	 * Returns the <code>ORMGenColumn</code> objects to be generated for this
	 * table.
	 */
	public List<ORMGenColumn> getColumns() {
		if (mColumns == null) {
			mColumns = new ArrayList<ORMGenColumn>();
			for (Column c : mDbTable.getColumns()) {
				ORMGenColumn genColumn = getCustomizer().createGenColumn(c);
				genColumn.setGenTable(this);
				mColumns.add(genColumn);
			}
		}
		return mColumns;
	}

	public List<String> getColumnNames() {
		List<String> ret = new ArrayList<String>();
		for (Column c : mDbTable.getColumns()) {
			ret.add(c.getName());
		}
		return ret;
	}

	/**
	 * Returns the <code>ORMGenColumn</code> objects representing the table's
	 * primary key.
	 */
	public List<ORMGenColumn> getPrimaryKeyColumns() {
		List<ORMGenColumn> ret = new ArrayList<ORMGenColumn>();
		for (Column column : mDbTable.getPrimaryKeyColumns()) {
			ret.add(new ORMGenColumn(column, this.mCustomizer));
		}
		return ret;
	}

	/**
	 * Returns the primary key column or null if there is no or many primary key
	 * columns.
	 */
	public ORMGenColumn getPrimaryKeyColumn() {
		ORMGenColumn pkCol = null;
		List<ORMGenColumn> pkColumns = getPrimaryKeyColumns();
		if (pkColumns.size() == 1) {
			// Column dbCol = (Column)pkColumns.get(0);
			pkCol = pkColumns.get(0); // (ORMGenColumn)
										// mCustomizer.createGenColumn(dbCol);
		}
		else {
			/*
			 * if no pk column then look for the first column with id mapping
			 * kind. This is so that the wizard can be used with tables not
			 * having primary keys.
			 */
			List<ORMGenColumn> columns = getColumns();
			for (int i = 0, n = columns.size(); i < n; ++i) {
				ORMGenColumn column = columns.get(i);
				if (column.getMappingKind().equals(mCustomizer.getIdMappingKind())) {
					pkCol = column;
					break;
				}
			}
		}
		return pkCol;
	}

	/**
	 * Returns true if there is more than 1 pk column.
	 */
	public boolean isCompositeKey() {
		return mDbTable.getPrimaryKeyColumnsSize() > 1;
	}

	/**
	 * Returns the <code>ORMGenColumn</code> objects for the the columns that
	 * are not part of any association.
	 * 
	 * @param genOnly
	 *            Whether to include only the columns marked for generation.
	 * 
	 * @param includePk
	 *            Whether to include the primary kley column(s).
	 * 
	 * @param includeInherited
	 *            Whether to include the columns associated with Java properties
	 *            that exist in the super class (if any).
	 */
	public List<ORMGenColumn> getSimpleColumns(boolean genOnly, boolean includePk, boolean includeInherited) {
		List<ORMGenColumn> result = new java.util.ArrayList<ORMGenColumn>();
		List<ORMGenColumn> columns = getColumns();
		List<AssociationRole> roles = getAssociationRoles();
		for (int i = 0, n = columns.size(); i < n; ++i) {
			ORMGenColumn column = columns.get(i);
			if (genOnly && !column.isGenerated()) {
				continue;
			}
			if (column.isPrimaryKey()) {
				if (!includePk || isCompositeKey()) {
					continue;
				} else {
					result.add(0, column);
					continue;
				}
			}
			else if (isColumnInAsscociation(column, roles)) {
				continue;
			}
			result.add(column);
		}
		return result;
	}

	public List<ORMGenColumn> getSimpleColumns() {
		return getSimpleColumns(true/* genOnly */, true/* includePk */, true/* includeInherited */);
	}

	/**
	 * Returns false if the given column should be generated with false
	 * updatable/insertable. This is the case when the column is mapped more
	 * than once, this usually happen with columns in composite keys and
	 * many-to-one associations.
	 * 
	 * <br>
	 * Note that for Hibernate the column param is null because the
	 * insert/update attributes are specified for the many-to-one tag itself
	 * instead of the nested column tags (bogus obviously).
	 */
	public boolean isColumnUpdateInsert(AssociationRole role, ORMGenColumn column) {
		if (column == null) {
			for (Iterator<ORMGenColumn> iter = role.getReferrerColumns().iterator(); iter.hasNext();) {
				ORMGenColumn c = iter.next();
				if (!isColumnUpdateInsert(role, c)) {
					return false;
				}
			}
			return true;
		}
		if (column.isPrimaryKey()) {
			return false;
		}
		/*
		 * should look if there are multiple associations using the same column
		 * and return false, but this is probably an unusual case.
		 */
		return true;
	}

	/**
	 * Returns the <code>ORMGenColumn</code> objects corresponding to the given
	 * column names.
	 */
	public List<ORMGenColumn> getColumnsByNames(List<String> names) {
		List<ORMGenColumn> result = new java.util.ArrayList<ORMGenColumn>();
		for (String name : names) {
			ORMGenColumn column = getColumnByName(name);
			assert (column != null);
			if (column != null) {
				result.add(column);
			}
		}
		return result;
	}

	/**
	 * Returns the columns having the given name, or null if none.
	 */
	public ORMGenColumn getColumnByName(String name) {
		List<ORMGenColumn> columns = getColumns();
		for (int i = 0, n = columns.size(); i < n; ++i) {
			ORMGenColumn column = columns.get(i);
			if (column.getName().equals(name)) {
				return column;
			}
		}
		return null;
	}

	/**
	 * Returns the <code>AssociationRole</code> objects for this table. Only the
	 * association marked for generation are returned.
	 */
	public List<AssociationRole> getAssociationRoles() {
		/*
		 * this is not cached intentionally because invalidating the cache with
		 * wizard changes is kinda tricky.
		 */
		List<AssociationRole> associationRoles = new ArrayList<AssociationRole>();
		String name = getName();
		List<Association> associations = mCustomizer.getAssociations();
		for (Iterator<Association> iter = associations.iterator(); iter.hasNext();) {
			Association association = iter.next();
			if (!association.isGenerated()) {
				continue;
			}
			/*
			 * check both referrerand referenced because an association could be
			 * from-to the same table (employee/manager)
			 */
			if (association.getReferrerTable().getName().equals(name)) {
				AssociationRole role = association.getReferrerRole();
				if (role != null) {
					associationRoles.add(role);
				}
			}
			if (association.getReferencedTable().getName().equals(name)) {
				AssociationRole role = association.getReferencedRole();
				if (role != null) {
					associationRoles.add(role);
				}
			}
		}
		return associationRoles;
	}

	public String getClassDescription() {
		return customized(CLASS_DESC);
	}

	/**
	 * Returns the generated class scope, one of {@link #PUBLIC_SCOPE}|
	 * {@link #PROTECTED_SCOPE} |{@link #PRIVATE_SCOPE}. This method never
	 * returns null (defaults to public).
	 */
	public String getClassScope() {
		String scope = customized(CLASS_SCOPE);
		if (scope == null) {
			scope = PUBLIC_SCOPE;
		}
		return scope;
	}

	public String getExtends() {
		return customized(EXTENDS);
	}

	public void setExtends(String baseClass) {
		setCustomized(EXTENDS, baseClass);
	}

	public List<String> getImplements() {
		String str = customized(IMPLEMENTS);
		List<String> result = StringUtil.strToList(str, ',', true/* trim */);
		if (result == null) {
			result = Collections.emptyList();
		}
		return result;
	}

	public void setImplements(List<String> interfaces) {
		setCustomized(IMPLEMENTS, StringUtil.listToStr(interfaces, ','));
	}

	/**
	 * Returns the string that should be generated in the Java class for extends
	 * and implements.
	 */
	public String generateExtendsImplements() {
		StringBuffer buffer = new StringBuffer();
		String extendsClass = getExtends();
		if (extendsClass != null && !extendsClass.equals("java.lang.Object") && !extendsClass.equals("Object")) {
			buffer.append("extends " + simplifyClassName(extendsClass) + " "); //fix for bug 278626
		}
		buffer.append("implements Serializable"); // assuming that the Java
													// file template imports the
													// java.io.Serializable
		for (Iterator<String> iter = getImplements().iterator(); iter.hasNext();) {
			buffer.append(", " + simplifyClassName(iter.next()));
		}
		return buffer.toString();
	}

	private String simplifyClassName(String fullClassName) {
		final String JAVA_LANG = "java.lang.";
		if (fullClassName.startsWith(JAVA_LANG)) {
			return fullClassName.substring(JAVA_LANG.length());
		}
		String pkg = StringUtil.getPackageName(fullClassName);
		if (pkg != null && StringUtil.equalObjects(pkg, getPackage())) {
			return StringUtil.getClassName(fullClassName);
		}
		return fullClassName;
	}

	/**
	 * Returns the id generator scheme (assigned, sequence, etc). Does not
	 * return null, defaults to "assigned" or "identity" depending on whether
	 * the table has an identity column.
	 */
	public String getIdGenerator() {
		String generator = customized(ID_GENERATOR);
		String noneGenerator = getCustomizer().getNoIdGenerator();
		if (!isDefaultsTable()) {
			/*
			 * This is done mainly because there might be cases where some
			 * tables have autoinctement pk and others are assigned. In this
			 * case this makes it so that it is possible to have a "none"
			 * default value that is interpreted depending on the case.
			 */
			if (generator == null || generator.equals(noneGenerator)) {
				ORMGenColumn pkColumn = getPrimaryKeyColumn();
				if (pkColumn != null && DTPUtil.isAutoIncrement(pkColumn.getDbColumn())) {
					generator = getCustomizer().getIdentityIdGenerator();
				}
			}
		}
		if (generator == null) {
			generator = noneGenerator;
		}
		return generator;
	}

	/**
	 * Changes the id generator scheme (assigned, sequence, etc).
	 */
	public void setIdGenerator(String scheme) {
		setCustomized(ID_GENERATOR, scheme);
	}

	/**
	 * Returns the sequence name for the given table, or null if none (makes
	 * sense only when the scheme is native, sequence, ..).
	 */
	public String getSequence() {
		return customized(SEQUENCE);
	}

	public void setSequence(String name) {
		setCustomized(SEQUENCE, name);
	}

	/**
	 * Returns the sequence name after replacing the ${table} and ${pk} by their
	 * values, or null if none.
	 */
	public String getFormattedSequence() {
		String sequence = getSequence();
		if (sequence != null) {
			/* resolve the ${table} and ${pk} patterns */
			sequence = StringUtil.strReplace(sequence, TABLE_SEQ_PATTERN, getName());
			if (sequence.indexOf(PK_SEQ_PATTERN) >= 0) {
				Iterator<Column> pkCols = getDbTable().getPrimaryKeyColumns().iterator();
				String pkName = pkCols.hasNext() ? pkCols.next().getName() : null;
				sequence = StringUtil.strReplace(sequence, PK_SEQ_PATTERN, pkName);
			}
		}
		return sequence != null ? sequence.toUpperCase() : "";
	}

	public boolean isImplementEquals() {
		return !"true".equals(customized(IMPLEMENT_EQUALS)); // defaults to
																// false
	}

	public void setImplementEquals(boolean value) {
		setCustomizedBoolean(IMPLEMENT_EQUALS, value, true);
	}

	/**
	 * Returns true if there is any column participating in equals/hashcode.
	 */
	public boolean hasColumnsInEquals() {
		List<ORMGenColumn> columns = getSimpleColumns();
		for (int i = 0, n = columns.size(); i < n; ++i) {
			ORMGenColumn column = columns.get(i);
			if (column.isUseInEquals()) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Returns {@link #GENERATE_DDL_ANNOTATION} indicating whether the optional
	 * DDL parameters like length, nullable, unqiue, etc should be generated in @Column
	 * annotation. defaults to false.
	 */
	public boolean isGenerateDDLAnnotations() {
		return "true".equals(customized(ORMGenCustomizer.GENERATE_DDL_ANNOTATION)); // defaults
																					// to
																					// false
	}

	public void setGenerateDDLAnnotations(boolean generate) {
		setCustomizedBoolean(ORMGenCustomizer.GENERATE_DDL_ANNOTATION, generate, false);
	}

	/**
	 * Returns one of {@link #PROPERTY_ACCESS}|{@link #FIELD_ACCESS} indicating
	 * how the entity properties are mapped. Does not return null (defaults to
	 * {@link #FIELD_ACCESS}).
	 */
	public String getAccess() {
		String name = customized(ACCESS);
		if (name == null) {
			name = FIELD_ACCESS;
		}
		return name;
	}

	public void setAccess(String access) {
		assert (access == null || access.equals(PROPERTY_ACCESS) || access.equals(FIELD_ACCESS));
		if (!StringUtil.equalObjects(access, getAccess())) {
			setCustomized(ACCESS, access);
		}
	}

	/**
	 * Returns one of {@link #LAZY_FETCH}|{@link #EAGER_FETCH} indicating how
	 * the table associations are feched. Returns null if the provider defaults
	 * should be used.
	 */
	public String getDefaultFetch() {
		return customized(DEFAULT_FETCH);
	}

	public void setDefaultFetch(String fetch) {
		assert (fetch == null || fetch.equals(LAZY_FETCH) || fetch.equals(EAGER_FETCH));
		setCustomized(DEFAULT_FETCH, fetch);
	}

	public String[] getSupportedCollectionTypes() {
		return new String[] {
			SET_COLLECTION_TYPE, LIST_COLLECTION_TYPE
		};
	}

	/**
	 * Returns one of {@link #LIST_COLLECTION_TYPE}|{@link #SET_COLLECTION_TYPE}
	 * indicating the Java type (full class name) used for properties of
	 * collection types. This does not return null (defaults to list).
	 */
	public String getDefaultCollectionType() {
		String cType = customized(DEFAULT_COLLECTION_TYPE);
		if (cType == null) {
			cType = SET_COLLECTION_TYPE;
		}
		return cType;
	}
	
	public String getSimpleCollectionType(){
		 String type = getDefaultCollectionType();
		return type.substring( type.lastIndexOf('.') +1 );
	}

	public void setDefaultCollectionType(String cType) {
		assert (cType.equals(LIST_COLLECTION_TYPE) || cType.equals(SET_COLLECTION_TYPE));
		setCustomized(DEFAULT_COLLECTION_TYPE, cType);
	}

	/**
	 * Returns true if the primary key is compound and any of its columns should
	 * be included in the <code>equals</code> method implementation.
	 */
	public boolean isCompoundKeyUseInEquals() {
		if (isCompositeKey()) {
			for (Iterator<ORMGenColumn> iter = getPrimaryKeyColumns().iterator(); iter.hasNext();) {
				ORMGenColumn column = iter.next();
				if (column.isUseInEquals()) {
					return true;
				}
			}
		}
		return false;
	}

	public boolean isRoleUseInEquals(AssociationRole role) {
		for (Iterator<ORMGenColumn> iter = role.getReferrerColumns().iterator(); iter.hasNext();) {
			ORMGenColumn column = iter.next();
			if (column.isUseInEquals()) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Return true if the values of name element in the @Table is default so we
	 * can skip generating the annotation
	 * 
	 * @return true
	 */
	public boolean isDefaultname() {
		String entityName = getClassName();
		String annotationName = this.mCustomizer.getDatabaseAnnotationNameBuilder().buildTableAnnotationName(entityName, mDbTable);
		return annotationName == null;
	}

	/**
	 * Qualifies a class name if there is a package.
	 */
	private String qualify(String className) {
		String pkg = getPackage();
		if (pkg != null && pkg.length() != 0) {
			className = pkg + '.' + className;
		}
		return className;
	}

	/**
	 * Returns true if the given column is part of any association.
	 */
	private boolean isColumnInAsscociation(ORMGenColumn column, List<AssociationRole> roles) {
		for (int i = 0, n = roles.size(); i < n; ++i) {
			AssociationRole role = roles.get(i);
			List<ORMGenColumn> cols = role.getReferrerColumns();
			for (ORMGenColumn col : cols) {
				if (col.getName().equals(column.getName())) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Print the clause to be used in the generated equals() method
	 * 
	 * @return String
	 */
	public String getPrimaryKeyEqualsClause() {
		StringBuilder buf = new StringBuilder();
		Iterator<ORMGenColumn> columns = this.getPrimaryKeyColumns().iterator();
		while (columns.hasNext()) {
			this.printPrimaryKeyEqualsClauseOn(columns.next(), buf);
			if (columns.hasNext()) {
				buf.append("\n");
				buf.append("\t\t\t");
				buf.append("&& ");
			}
		}
		buf.append(";");
		return buf.toString();
	}

	private void printPrimaryKeyEqualsClauseOn(ORMGenColumn column, StringBuilder buf) {
		String fieldName = column.getPropertyName();
		JavaType javaType = column.getDbColumn().getPrimaryKeyJavaType();
		if (javaType.isPrimitive()) {
			this.printPrimitiveEqualsClauseOn(fieldName, buf);
		}
		else {
			this.printReferenceEqualsClauseOn(fieldName, buf);
		}
	}

	private void printPrimitiveEqualsClauseOn(String fieldName, StringBuilder buf) {
		buf.append("(this.");
		buf.append(fieldName);
		buf.append(" == castOther.");
		buf.append(fieldName);
		buf.append(')');
	}

	private void printReferenceEqualsClauseOn(String fieldName, StringBuilder buf) {
		buf.append("this.");
		buf.append(fieldName);
		buf.append(".equals(castOther.");
		buf.append(fieldName);
		buf.append(')');
	}

	/**
	 * Print the clause to be used in the generated hasCode() method
	 * 
	 * @return String
	 */
	public String getPrimaryKeyHashCodeClause() {
		StringBuilder buf = new StringBuilder();
		Iterator<ORMGenColumn> columns = this.getPrimaryKeyColumns().iterator();
		while (columns.hasNext()) {
			buf.append("hash = hash * prime + ");
			this.printPrimaryKeyHashCodeClauseOn(columns.next(), buf);
			buf.append(';');
			buf.append('\n');
			buf.append("\t\t");
		}
		return buf.toString();
	}

	private void printPrimaryKeyHashCodeClauseOn(ORMGenColumn column, StringBuilder buf) {
		String fieldName = column.getPropertyName();
		JavaType javaType = column.getDbColumn().getPrimaryKeyJavaType();
		if (javaType.isPrimitive()) {
			this.printPrimitiveHashCodeClauseOn(javaType.getElementTypeName(), fieldName, buf);
		}
		else {
			this.printReferenceHashCodeClauseOn(fieldName, buf);
		}
	}

	private void printPrimitiveHashCodeClauseOn(String primitiveName, String fieldName, StringBuilder buf) {
		if (primitiveName.equals("int")) {
			// this.value
			buf.append("this.");
			buf.append(fieldName);
		}
		else if (primitiveName.equals("short") || primitiveName.equals("byte") || primitiveName.equals("char")) { // explicit
																													// cast
			// ((int) this.value)
			buf.append("((int) this.");
			buf.append(fieldName);
			buf.append(')');
		}
		else if (primitiveName.equals("long")) { // cribbed from Long#hashCode()
			// ((int) (this.value ^ (this.value >>> 32)))
			buf.append("((int) (this.");
			buf.append(fieldName);
			buf.append(" ^ (this.");
			buf.append(fieldName);
			buf.append(" >>> 32)))");
		}
		else if (primitiveName.equals("float")) { // cribbed from
													// Float#hashCode()
			// java.lang.Float.floatToIntBits(this.value)
			buf.append("java.lang.Float");
			buf.append(".floatToIntBits(this.");
			buf.append(fieldName);
			buf.append(')');
		}
		else if (primitiveName.equals("double")) { // cribbed from
													// Double#hashCode()
			// ((int) (java.lang.Double.doubleToLongBits(this.value) ^
			// (java.lang.Double.doubleToLongBits(this.value) >>> 32)))
			buf.append("((int) (");
			buf.append("java.lang.Double");
			buf.append(".doubleToLongBits(this.");
			buf.append(fieldName);
			buf.append(") ^ (");
			buf.append("java.lang.Double");
			buf.append(".doubleToLongBits(this.");
			buf.append(fieldName);
			buf.append(") >>> 32)))");
		}
		else if (primitiveName.equals("boolean")) {
			// (this.value ? 1 : 0)
			buf.append("(this.");
			buf.append(fieldName);
			buf.append(" ? 1 : 0)");
		}
		else {
			throw new IllegalArgumentException(primitiveName);
		}
	}

	private void printReferenceHashCodeClauseOn(String fieldName, StringBuilder buf) {
		buf.append("this.");
		buf.append(fieldName);
		buf.append(".hashCode()");
	}

	@Override
	public String toString() {
		return "name=" + this.getName() + "; columns=" + Arrays.toString(this.getColumnNames().toArray());
	}

	/* class scopes */
	public static final String PUBLIC_SCOPE = "public";

	public static final String PROTECTED_SCOPE = "protected";

	public static final String PRIVATE_SCOPE = "private";

	/* access constants. Note that these strings are used in the ui */
	public static final String PROPERTY_ACCESS = "property";

	public static final String FIELD_ACCESS = "field";

	/*
	 * default fech constants. Note that these strings are used in the gen
	 * velocity templates.
	 */
	public static final String DEFAULT_FETCH = "defaultFetch";

	public static final String LAZY_FETCH = "lazy";

	public static final String EAGER_FETCH = "eager";

	/*
	 * default collection type constants. Note that these strings are used in
	 * the gen velocity templates.
	 */
	public static final String LIST_COLLECTION_TYPE = "java.util.List";

	public static final String SET_COLLECTION_TYPE = "java.util.Set";

	/**
	 * The pattern replaced by the table name in the id generator sequence name
	 * param.
	 */
	public static final String TABLE_SEQ_PATTERN = "$table";

	/**
	 * The pattern replaced by the primary key in the id generator sequence name
	 * param.
	 */
	public static final String PK_SEQ_PATTERN = "$pk";

	/* customization properties */
	private static final String PACKAGE = "package";

	private static final String SRC_FOLDER = "srcFolder";

	private static final String CLASS_NAME = "className";

	private static final String CLASS_DESC = "classDesc";

	private static final String CLASS_SCOPE = "classScope";

	private static final String EXTENDS = "extends";

	private static final String IMPLEMENTS = "implements";

	private static final String ID_GENERATOR = "idGenerator";

	private static final String SEQUENCE = "sequence";

	private static final String COMPOSITE_KEY_CLASS_NAME = "compositeKeyClassName";

	private static final String IMPLEMENT_EQUALS = "implementEquals";

	private static final String ACCESS = "access";

	private static final String DEFAULT_COLLECTION_TYPE = "defaultCollectionType";
}
