/*******************************************************************************
 * 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, getTableName(), null);
	}

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

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

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

	public Table getDbTable() {
		return mDbTable;
	}

	/**
	 * Returns the table name.
	 */
	public String getTableName() {
		return mDbTable != null ? mDbTable.getName() : ORMGenCustomizer.ANY_TABLE;
	}
	
	public String getName() {
 		if (mDbTable == null)
 			return ORMGenCustomizer.ANY_TABLE;
		String tableName = getTableName();
		String annotationName = this.mCustomizer.getDatabaseAnnotationNameBuilder().buildTableAnnotationName(tableName, mDbTable);
		return annotationName != null ? annotationName : tableName;
	}

	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(getTableName(), 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(getTableName());
		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";
}
