/*******************************************************************************
 * Copyright (c) 2007, 2008 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.internal2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
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.internal2.util.DTPUtil;
import org.eclipse.jpt.gen.internal2.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;
	
	/**
	 * @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;
		String annotationName = this.mCustomizer.getDatabaseAnnotationNameBuilder().
			buildTableAnnotationName(mDbTable.getName(), mDbTable);
		return annotationName != null ? annotationName : 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 ))
			return "";
		String schemaName = mDbTable.getSchema().getName();
		
		return schemaName;
	}
	/**
	 * Sets the package for the generated class (empty string for the default package)
	 */
	public void setPackage(String srcFolder, String pkg) {
		setCustomized(SRC_FOLDER, srcFolder);
		
		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() {
		return customized(PACKAGE);
	}

	/**
	 * 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 = 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";
		}
		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 "compId";
	}
	/**
	 * Returns the <code>ORMGenColumn</code> objects to be 
	 * generated for this table.
	 */
	public List<ORMGenColumn> getColumns() {
		if (mColumns == null) {
			mColumns = new ArrayList<ORMGenColumn>(); 
			Iterator<Column> cols = mDbTable.columns();
			while (cols.hasNext() ) {
				Column c = cols.next();
				ORMGenColumn genColumn = getCustomizer().createGenColumn( c );
				mColumns.add( genColumn );
			}
		}
		return mColumns;
	}
	public List<String> getColumnNames() {
		Iterator<Column> cols = mDbTable.columns();
		List<String> ret = new ArrayList<String>();
		while (cols.hasNext() ) {
			Column c = cols.next(); 
			ret.add(c.getName());
		}
		return ret;
	}
	/**
	 * Returns the <code>ORMGenColumn</code> objects representing 
	 * the table's primary key.
	 */
	public List<ORMGenColumn> getPrimaryKeyColumns()  {
		List<Column> dbCols = DTPUtil.getPrimaryKeyColumns( mDbTable);
		List<ORMGenColumn> ret = new ArrayList<ORMGenColumn>();
		for(Column dbCol : dbCols ){
			ret.add(new ORMGenColumn(dbCol, 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 = (ORMGenColumn)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 DTPUtil.getPrimaryKeyColumnNames( mDbTable ).size() > 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 = (ORMGenColumn)columns.get(i);
			if (genOnly && !column.isGenerated()) {
				continue;
			}
			if (column.isPrimaryKey()) {
				if (!includePk || isCompositeKey()) {
					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 = (ORMGenColumn)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 = (ORMGenColumn)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 = (Association)iter.next();
			if (!association.isGenerated()) {
				continue;
			}
			/*check both referrer *and* 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));
		}
		
		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((String)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 setSeqence(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) {
				 List<String> pkNames = DTPUtil.getPrimaryKeyColumnNames( getDbTable() );
				 String pkName = null;
				 if (pkNames.size()>0 ) {
				 	pkName = (String)pkNames.get(0);
				 }
				 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 = (ORMGenColumn)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(GENERATE_DDL_ANNOTATION)); //defaults to false
	}
	
	public void setGenerateDDLAnnotations(boolean generate) {
		setCustomizedBoolean(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 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 = (ORMGenColumn) 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 = (ORMGenColumn) 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 className = this.getClassName();
		String tableName = this.getDbTable().getName();
		return className.equalsIgnoreCase( tableName) ;
	}
	
	/**
	 * 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 = (AssociationRole)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()");
	}
	
	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 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 GENERATE_DDL_ANNOTATION = "generateDDLAnnotations";
	private static final String ACCESS = "access";
	static final String DEFAULT_FETCH = "defaultFetch";
	private static final String DEFAULT_COLLECTION_TYPE = "defaultCollectionType";

}
