/*******************************************************************************
 * Copyright (c) 2007, 2009 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.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.db.Column;
import org.eclipse.jpt.db.Table;
import org.eclipse.jpt.gen.internal.old.EntityGenTools;
import org.eclipse.jpt.gen.internal.util.DTPUtil;
import org.eclipse.jpt.gen.internal.util.StringUtil;
import org.eclipse.jpt.utility.JavaType;

/**
 * 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";
}
