/*******************************************************************************
 * 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.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.jpa.db.Column;
import org.eclipse.jpt.jpa.db.Schema;
import org.eclipse.jpt.jpa.db.Table;
import org.eclipse.jpt.jpa.gen.internal.util.DTPUtil;
import org.eclipse.jpt.jpa.gen.internal.util.FileUtil;
import org.eclipse.jpt.jpa.gen.internal.util.ForeignKeyInfo;
import org.eclipse.jpt.jpa.gen.internal.util.StringUtil;

/**
 * Contains the information used to customize the database schema to ORM entity 
 * generation.
 * 
 * <p>The customization settings are mainly exposed in the form of 
 * properties. There are no assumptions in this class about the meaning of the 
 * property names. Properties can be associated to specific tables and table 
 * columns, or globally for any table and/or column.
 * 
 * <p>Subclass can implement the sets of abstract methods to provide ORM vendor
 * specific properties.
 * 
 */
public abstract class ORMGenCustomizer implements java.io.Serializable
{
	private final static long serialVersionUID = 1;

	/**
	 * A value passed for the table name argument to get/setProperty 
	 * indicating that the value applies to any table.
	 */
	public static final String ANY_TABLE = "__anyTable__";
	public static final String GENERATE_DDL_ANNOTATION = "generateDDLAnnotations";
	/*the string used in the property name in mProps to indicate 
	 * a null table value.*/
	private static final String NULL_TABLE = "";
	/*the string used in the property name in mProps to indicate 
	 * a null column value.*/
	private static final String NULL_COLUMN = "";
	
	/*This version number is written in the header of the customization stream
	 * and read at de-serialization time, if it is different then the file is invalidated.
	 */
	private static final int FILE_VERSION = 2;
	
	private static final String UPDATE_CONFIG_FILE = "updateConfigFile";

	private transient Schema mSchema;
	private transient File mFile;
	
	private List<String> mTableNames;
	/*key: table name, value: ORMGenTable object.*/
	private transient Map<String , ORMGenTable> mTables;
	/*the <code>Association</code> objects sorted by their "from" 
	 * table name. Includes all association derived from foreign keys 
	 * in user selected tables. Since some of the foreign keys may point to table
	 * user does not select, this list may be different from  mValidAssociations
	 */
	private List<Association> mAssociations;
	/*
	 * List of valid associations within the user selected tables  
	 */
	private transient List<Association> mValidAssociations;
	private transient boolean mInvalidForeignAssociations;
	
	/*the property name is in the form $tableName.$columnName.$propertyName.
	 * Where tableName could be NULL_TABLE or ANY_TABLE
	 * and columnName could be NULL_COLUMN*/
	private Map<String, String> mProps = new java.util.HashMap<String, String>();

	private transient DatabaseAnnotationNameBuilder databaseAnnotationNameBuilder = DatabaseAnnotationNameBuilder.Default.INSTANCE;

	private boolean mUpdatePersistenceXml = true;
	
	//EclipseLink mapping file default name
	private static final String DEFAULT_XML_MAPPING_FILE = "META-INF/eclipselink-orm.xml";
	private static final String XML_MAPPING_FILE = "xmlMappingFileName";
	
	
	//-----------------------------------------
	//---- abstract methods
	//-----------------------------------------
	/**
	 * Returns all the primary key generator schemes.
	 * This can return any strings as far as the Velocity template 
	 * processor understand them.
	 */
	public abstract List<String> getAllIdGenerators();
	/**
	 * Returns the string representing the developer-assigned id generator.
	 * This can return any strings as far as the Velocity template 
	 * processor understand them.
	 */
	public abstract String getNoIdGenerator();
	/**
	 * Returns the string representing the identity id generator.
	 * This can return any strings as far as the Velocity template 
	 * processor understand them.
	 */
	public abstract String getIdentityIdGenerator();
	/**
	 * Returns the strings representing the sequence generators.
	 * This can return any strings as far as the Velocity template 
	 * processor understand them.
	 */
	public abstract Set<String> getSequenceIdGenerators();
	/**
	 * Returns a property type from the given database column.
	 * This can return any strings as far as the Velocity template 
	 * processor understand them.
	 */
	public abstract String getPropertyTypeFromColumn(Column column) ;
	/**
	 * Returns all the strings representing property types.
	 * This can return any strings as far as the Velocity template 
	 * processor understand them.
	 */
	public abstract String[] getAllPropertyTypes();
	/**
	 * Returns all the strings representing property mapping kinds.
	 * This can return any strings as far as the Velocity template 
	 * processor understand them.
	 */
	public abstract String[] getAllMappingKinds();
	/**
	 * Returns the basic (default) property mapping kind.
	 * This can return any strings as far as the Velocity template 
	 * processor understand them.
	 */
	public abstract String getBasicMappingKind();
	/**
	 * Returns the id (primary key) property mapping kind.
	 * This can return any strings as far as the Velocity template 
	 * processor understand them.
	 */
	public abstract String getIdMappingKind();
	/**
	 * Interacts with the user to edit the cascade of the given 
	 * role.
	 * This method should also call <code>AssociationRole.setCascade</code>.
	 * 
	 * @return false if the user interaction is cancelled.
	 */
	public abstract boolean editCascade(AssociationRole role);
	
	//-----------------------------------------
	//-----------------------------------------

	/**
	 * @param file The file that contains the customization settings.
	 * The file is created if necessary when the <code>save</code> 
	 * method is called.
	 */
	public void init( File file, Schema schema) {
		this.mSchema = schema;
		mFile = file;
		
		if (!file.exists()) {
			setProperty(ORMGenTable.DEFAULT_FETCH, ORMGenTable.DEFAULT_FETCH, ORMGenCustomizer.ANY_TABLE, null);
			return;
		}
		InputStream istream = null;
		ObjectInputStream ois = null;
		try 
		{
			//read it in a file first to speedup deserialization
			byte[] bytes = FileUtil.readFile(file);
			istream = new ByteArrayInputStream(bytes);
			ois = new ObjectInputStream(istream);
			
			FileHeader header = (FileHeader)ois.readObject();
			if (header.mVersion == FILE_VERSION) {
				ORMGenCustomizer customizer = (ORMGenCustomizer)ois.readObject();
				restore(customizer);
			}
		} catch (Exception ex) {
			JptJpaGenPlugin.logException("***ORMGenCustomizer.load failed "+file, ex);				
		}
		finally 
		{
			if (ois != null)
			{
				try 
				{
					ois.close();
				} catch (IOException e) {
				}
			}
			
			if (istream != null)
			{
				try 
				{
					istream.close();
				} catch (IOException e) {
				}
			}
		}
	}
	
	public File getFile(){
		return this.mFile;
	}
	
	public void setSchema(Schema schema){
		this.mSchema = schema;
	}

	public Schema getSchema(){
		return mSchema;
	}
	
	/**
	 * Empty constructor needed by the deserialization.
	 */
	public ORMGenCustomizer() {
		super();
	}

	/**
	 * Saves the customization file.
	 * The file is created if necessary.
	 */
	public void save() throws IOException {
		//System.out.println("---ORMGenCustomizer.save: " + mFile);
		if (!mFile.exists() && !mFile.createNewFile()) {
			return;
		}
		java.io.FileOutputStream fos = null;
		java.io.ObjectOutputStream oos = null;
		boolean deleteIt = true;
		try {
			fos = new java.io.FileOutputStream(mFile);
			oos = new java.io.ObjectOutputStream(fos);
			FileHeader header = new FileHeader();
			oos.writeObject(header);
			oos.writeObject(this);
			deleteIt = false;
		} catch (Exception ex) {
			//deleteIt is true, so the cache is not saved.
			CoreException ce = new CoreException(new Status(IStatus.ERROR, JptJpaGenPlugin.PLUGIN_ID,
					"Unable to save the ORMGenCustomizer file: "+mFile,ex));
			JptJpaGenPlugin.logException( ce );
		} finally {
			try {
				if (oos!=null) oos.close();
				if (fos!=null) fos.close();
				if (deleteIt) {
					mFile.delete();
				}
			} catch (java.io.IOException ex2) {}	
		}
	}
	
	public DatabaseAnnotationNameBuilder getDatabaseAnnotationNameBuilder() {
		return this.databaseAnnotationNameBuilder;
	}
	public void setDatabaseAnnotationNameBuilder(DatabaseAnnotationNameBuilder databaseAnnotationNameBuilder) {
		if (databaseAnnotationNameBuilder == null) {
			throw new NullPointerException("database annotation name builder is required");  //$NON-NLS-1$
		}
		this.databaseAnnotationNameBuilder = databaseAnnotationNameBuilder;
	}	

	/**
	 * 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(getProperty(GENERATE_DDL_ANNOTATION, ANY_TABLE, null)); //defaults to false
	}

	/**
	 * Returns a property value.
	 */
	public String getProperty(String propertyName, String tableName, String colName) {
		String key = getPropKey(propertyName, tableName, colName);
		String value = mProps.get(key);
		/*if the key does not exist and it is a table property then 
		 * get the default table property.*/
		if (value == null && tableName != null && colName == null && !tableName.equals(ANY_TABLE)) {
			value = getProperty(propertyName, ANY_TABLE, colName);
		}
		return value;
	}
	/**
	 * Changes a property value.
	 * 
	 * @param value The new value, could be null.
	 */
	public void setProperty(String propertyName, String value, String tableName, String colName) {
		String key = getPropKey(propertyName, tableName, colName);
		if (value != null) {
			mProps.put(key, value);
		} else {
			mProps.remove(key);
		}
	}
	/**
	 * Same as {@link #getProperty(String, String, String)} but 
	 * converts the value to boolean.
	 */
	public boolean getBooleanProperty(String propertyName, String tableName, String colName) {
		String value = getProperty(propertyName, tableName, colName);
		return "true".equals(value);
	}
	/**
	 * Changes a table boolean property value.
	 */
	public void setBooleanProperty(String propertyName, boolean value, String tableName, String colName) {
		setProperty(propertyName, value ? "true" : "false", tableName, colName);
	}
	/**
	 * Returns the names of the tables to generate.
	 */
	@SuppressWarnings("unchecked")
	public List<String> getTableNames() {
		return mTableNames != null ? mTableNames : java.util.Collections.EMPTY_LIST;
	}
	
	/**
	 * Returns the fetch type annotation member value, or empty string 
	 * if none.
	 * Empty string is returned instead of null because Velocity does not like null 
	 * when used in #set.
	 */
	public String genFetch(ORMGenTable table) {
		return "";
	}	
	
	public String genFetchXml(ORMGenTable table) {
		return "";
	}	
	
	/**
	 * XML Mapping File Path
	 */
	public void setXmlMappingFile(String xmlMappingFile) {
		setProperty(XML_MAPPING_FILE, xmlMappingFile, null, null); 
	}

	/**
	 * XML Mapping File Path
	 */
	public String getXmlMappingFile() {
		String xmlMappingFile = getProperty(XML_MAPPING_FILE, null, null);
		return xmlMappingFile == null ? DEFAULT_XML_MAPPING_FILE : xmlMappingFile; //$NON-NLS-1$
	}
	
	
	/**
	 * Called when the table user selection is changed in the 
	 * generation wizard.
	 */
	public void setTableNames(List<String> tableNames) {
		mTableNames = tableNames;
		mTables = null;
		mValidAssociations = null; //recompute
		mInvalidForeignAssociations = true; //make sure foreign associations from newly added tables are computed.
	}
	/**
	 * Returns the table names to be generated.
	 * This might be different from <code>getTableNames</code> if there 
	 * are many-to-many join tables and are not contributing 
	 * in any other associations.
	 */
	public List<String> getGenTableNames()  {
		List<String> names = getTableNames();
		List<String> result = new java.util.ArrayList<String>(names.size());
		
		/*filter out join tables*/
		List<Association> associations = getAssociations();
		for (Iterator<String> tableNamesIter = names.iterator(); tableNamesIter.hasNext(); ) {
			String tableName = tableNamesIter.next();
			boolean isValid = true;
			
			for (Iterator<Association> assocIter = associations.iterator(); assocIter.hasNext(); ) {
				Association association = assocIter.next();
				if (!association.isGenerated()) {
					continue;
				}
				if (tableName.equals(association.getReferrerTableName())
						|| tableName.equals(association.getReferencedTableName())) {
					isValid = true;
					break;
				}
				if (tableName.equals(association.getJoinTableName())) {
					isValid = false;
				}
			}
			if (isValid) {
				result.add(tableName);
			}
		}
		return result;
	}
	/**
	 * Returns an <code>ORMGenTable</code> object given its name, or 
	 * null if none.
	 */
	public ORMGenTable getTable(String tableName)  {
		if (mTables == null) {
			mTables = new java.util.HashMap<String, ORMGenTable>(mTableNames.size());
		}
		
		if(mTableNames!=null && mSchema!=null){
			for (Iterator<String> iter = mTableNames.iterator(); iter.hasNext(); ) {
				String name = iter.next();
				Table dbTable = mSchema.getTableNamed( name );
				if (dbTable != null) {
					mTables.put(name, createGenTable(dbTable));
				}
			}
		}
		return mTables.get(tableName);
	}
	/**
	 * Returns the <code>Association</code> objects sorted by their "from" 
	 * table name.
	 */
	public List<Association> getAssociations(){
		return getAssociations(true/*validOnly*/);
	}
	/**
	 * Adds the given association.
	 */
	public void addAssociation(Association association)  {
		getAssociations(false/*validOnly*/).add(association);
		if (mValidAssociations != null) {
			mValidAssociations.add(association);
		}
		
	}
	/**
	 * Deletes the given association.
	 */
	public void deleteAssociation(Association association)  {
		boolean removed = getAssociations(false/*validOnly*/).remove(association);
		assert(removed);
		
		if (mValidAssociations != null) {
			removed = mValidAssociations.remove(association);
			assert(removed);
		}
	}
	/**
	 * Returns true if an association similar to the given association 
	 * already exists.
	 * This is decided based only on the association tables and columns.
	 */
	public boolean similarAssociationExists(Association association) {
		try {
			for (Iterator<Association> iter = getAssociations(false/*validOnly*/).iterator(); iter.hasNext(); ) {
				Association association2 = iter.next();
				if (!association.getReferrerTableName().equals(association2.getReferrerTableName())
						|| !association.getReferencedTableName().equals(association2.getReferencedTableName())
						|| !StringUtil.equalObjects(association.getJoinTableName(), association2.getJoinTableName())
						|| !association.getReferrerColumnNames().equals(association2.getReferrerColumnNames())
						|| !association.getReferencedColumnNames().equals(association2.getReferencedColumnNames())
						) {
					continue;
				}					
				/*the 2 association have the same referrer, referenced and join table*/
				if (association.getJoinTableName() == null) {
					return true;
				}
				if (association.getReferrerJoinColumnNames().equals(association2.getReferrerJoinColumnNames())
						&& association.getReferencedJoinColumnNames().equals(association2.getReferencedJoinColumnNames())) {
					return true;
				}
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	/**
	 * Creates the <code>ORMGenTable</code> instance. 
	 */
	public ORMGenTable createGenTable(Table dbTable) {
		return new ORMGenTable(dbTable, this);
	}
	/**
	 * Creates the <code>ORMGenColumn</code> instance.
	 */
	protected ORMGenColumn createGenColumn(Column dbCol) {
		return new ORMGenColumn(dbCol, this);
	}
	/**
	 * Returns true of the underlying persistence specs require the "many" side 
	 * of an association to be the owner (like EJB3).
	 */
	protected boolean manySideIsAssociationOwner() {
		return false;
	}
	public boolean isUpdateConfigFile() {
		return !"false".equals(getProperty(UPDATE_CONFIG_FILE, null, null)); //defaults to true
	}
	public void setUpdateConfigFile(boolean value) {
		if (value) { //default is true
			setProperty(UPDATE_CONFIG_FILE, null, null, null); //remove it
		} else {
			setBooleanProperty(UPDATE_CONFIG_FILE, value, null, null);
		}
	}

	//-----------------------------------------
	//---- Velocity templates methods
	//-----------------------------------------
	/**
	 * Returns a getter method name given a property name.
	 */
	public String propertyGetter(String propertyName) {
		return "get"+StringUtil.initUpper(propertyName);
	}
	/**
	 * Returns a setter method name given a property name.
	 */
	public String propertySetter(String propertyName) {
		return "set"+StringUtil.initUpper(propertyName);
	}
	public String quote(String s) {
		return StringUtil.quote(s, '"');
	}
	public String quote(boolean b) {
		return quote(String.valueOf(b));
	}
	public String quote(int i) {
		return quote(String.valueOf(i));
	}
	public String convertToJavaStringLiteral(String s) {
		return StringTools.convertToJavaStringLiteral(s);
	}
	public String convertToXmlStringLiteral(String s) {
		return StringTools.convertToXmlStringLiteral(s);
	}
	/**
	 * Appends an annotation member name and value to an existing annotation.
	 * 
	 * @param s The annotation members string.
	 *
	 * @param memberValue The member value, if null or empty strings then 
	 * nothing is appened.
	 * 
	 * @param whether to double quote the member value.
	 */
	public String appendAnnotation(String s, String memberName, String memberValue, boolean quote) {
		if (memberValue == null || memberValue.length() == 0) {
			return s;
		}
		StringBuffer buffer = new StringBuffer(s);
		if (buffer.length() != 0) {
			buffer.append(", ");
		}
		buffer.append(memberName);
		buffer.append('=');
		if (quote) {
			buffer.append('"');
		}
		buffer.append(memberValue);
		if (quote) {
			buffer.append('"');
		}
		return buffer.toString();
	}
	
	/**
	 * Appends an attribute name and value to an existing element.
	 * 
	 * @param s The attribute key string.
	 *
	 * @param memberValue The attribute value, if null or empty strings then 
	 * nothing is appened.
	 * 
	 * @param whether to double quote the member value.
	 */
	public String appendAttribute(String s, String memberName, String memberValue, boolean quote) {
		if (memberValue == null || memberValue.length() == 0) {
			return s;
		}
		StringBuffer buffer = new StringBuffer(s);
		if (buffer.length() != 0) {
			buffer.append(" ");
		}
		buffer.append(memberName);
		buffer.append('=');
		if (quote) {
			buffer.append('"');
		}
		buffer.append(memberValue);
		if (quote) {
			buffer.append('"');
		}
		return buffer.toString();
	}
	
	public boolean isJDK1_5() {
		return true;
	}
	
	//-----------------------------------------
	//---- private methods
	//-----------------------------------------
	/**
	 * Restores the customization settings from the given 
	 * (persisted) customizer.
	 */
	private void restore(ORMGenCustomizer customizer)  {
		mTableNames = customizer.mTableNames;
		mAssociations = customizer.mAssociations;
		mProps = customizer.mProps;
		mUpdatePersistenceXml = customizer.mUpdatePersistenceXml;
		if( mSchema == null )
			return;
		
		/*remove invalid table names*/
		for (int i = mTableNames.size()-1; i >= 0; --i) {
			String tableName = mTableNames.get(i);
			if (mSchema.getTableNamed( tableName) == null) {
				mTableNames.remove(i);
			}
		}
		if( mAssociations!=null ){
			/*restore the associations*/
			for (Iterator<Association> iter = mAssociations.iterator(); iter.hasNext(); ) {
				Association association = iter.next();
				association.restore(this);
			}
			/*add the foreign keys associations just in case the tables changed since 
			 * the last time the state was persisted. Pass checkExisting true so that the 
			 * associations restored above are not overwritten.*/
			addForeignKeyAssociations(true/*checkExisting*/);
			// sort on restore
			sortAssociations( mAssociations );
		}
	}
	/**
	 * Returns the key in mProps corresponding to the specified 
	 * propertyName, table and column.
	 */
	private String getPropKey(String propertyName, String tableName, String colName) {
		if (tableName == null) {
			tableName = NULL_TABLE;
		}
		if (colName == null) {
			colName = NULL_COLUMN;
		}
		return tableName + '.' + colName + '.' + propertyName;
	}
	/**
	 * Returns the associations that are valid for the 
	 * current tables.
	 */
	private List<Association> getAssociations(boolean validOnly){
		if (mAssociations == null) {
			mAssociations = new java.util.ArrayList<Association>();
			
			addForeignKeyAssociations(false/*checkExisting*/);
		} else if (mInvalidForeignAssociations) {
			mInvalidForeignAssociations = false;
			
			addForeignKeyAssociations(true/*checkExisting*/);
		}
		List<Association> associations;
		if (validOnly) {
			if (mValidAssociations == null) {
				/*filter out the invalid associations*/
				mValidAssociations = new ArrayList<Association>(mAssociations.size());
				for (int i = 0, n = mAssociations.size(); i < n; ++i) {
					Association association = mAssociations.get(i);
					if (association.isValid()) {
						mValidAssociations.add(association);
					}
				}
			}
			associations = mValidAssociations;
		} else {
			associations = mAssociations;
		}
		return associations;
	}
	private void addForeignKeyAssociations(boolean checkExisting) {
		List<String> tableNames = getTableNames();
		for (Iterator<String> iter = tableNames.iterator(); iter.hasNext(); ) {
			ORMGenTable table = getTable(iter.next());
			addForeignKeyAssociations(table, checkExisting);
		}
	}
	private void addForeignKeyAssociations(ORMGenTable table, boolean checkExisting) {
		if(table==null)
			return;
		
		
		List<ForeignKeyInfo> fKeys = null;
		
		try{
			fKeys = DTPUtil.getForeignKeys(table.getDbTable());
		}catch(Exception ise){
			//workaround Dali bug for now
			return;
		}
		
		if( fKeys.size()==0 )
			return;
		
		List<Association> addedAssociations = new java.util.ArrayList<Association>();
		for (Iterator<ForeignKeyInfo> iter = fKeys.iterator(); iter.hasNext(); ) {
			ForeignKeyInfo fki = iter.next();
			ORMGenTable referencedTable = getTable(fki.getReferencedTableName());
			if (referencedTable == null) {
				continue;
			}
			Association association = new Association(this, table.getName(), fki.getReferrerColumnNames()
						, referencedTable.getName(), fki.getReferencedColumnNames());
			association.computeCardinality();
			//Defer the check of similarAssociationExists after computeManyToMany()
			//otherwise the MTM association will not computed correctly in some cases.
			//if (checkExisting && similarAssociationExists(association)) {
			//	continue;
			//}
			addedAssociations.add(association);
		}
		
		Association m2m = computeManyToMany(table, addedAssociations);
		if (m2m != null) {
			/*do not generate the 2 many-to-one*/
			addedAssociations.clear();
			addedAssociations.add(0, m2m);
		}
		//remove the association if already existing
		Iterator<Association> it =  addedAssociations.iterator(); 
		while( it.hasNext() ){
			Association newAssociation = it.next();
			for( Association association : mAssociations ){
				if( newAssociation.equals( association )){
					it.remove();
					break;
				}
			}
		}
		mAssociations.addAll(addedAssociations);
	}
	private Association computeManyToMany(ORMGenTable table, List<Association> addedAssociations) {
		/** many-to-many associations if:
		 * - addedAssociations contains 2 many-to-one associations
		 * - tables t1 and t2 does NOT have to be different( for self-MTM-self situation)
		 * - <code>table</code> contains only the foreign key columns.
		 * 
		 * Note: following restrictions have been removed:
		 * -table has only two columns
		 * -t1 and t2 must be different
		 * -the primary key of <code>table</code> is the concatenation of its foreign 
		 * 	keys to t1 and t2.*/
		
		if (addedAssociations.size() != 2) {
			return null;
		}
		
		//MTM table should have two MTO relations to orginal tables
		Association assoc1 = addedAssociations.get(0);
		Association assoc2 = addedAssociations.get(1);
		if (assoc1.getCardinality() != Association.MANY_TO_ONE
				|| assoc2.getCardinality() != Association.MANY_TO_ONE) {
			return null;
		}

		//MTM table should only include foreign key columns
		for( ORMGenColumn col : table.getColumns()){
			if( !col.isForeignKey())
				return null;
		}
		

		ORMGenTable t1 = assoc1.getReferencedTable();
		ORMGenTable t2 = assoc2.getReferencedTable();

		if( t1.getName().equals(table.getName()) || t2.getName().equals(table.getName()) ) {
			return null;
		}

		//Make a guess which table is the owning side of the MTM relation
		//See https://bugs.eclipse.org/bugs/show_bug.cgi?id=268445
		//Logic borrowed from DTPTableWrapper.getJoinTableOwningForeignKey()
		if( !table.getName().equals(t1.getName() + "_" + t2.getName() ) ) {
			//swap t1 and t2  
			ORMGenTable t3 = t1;
			t1=t2;
			t2=t3;
			//swap assoc1 and assoc2
			Association assoc3=assoc1;
			assoc1=assoc2;
			assoc2=assoc3;
		}
		
//Commented out because the assumption is too restrictive: 
//this check will prevent generating MTM mapping table not having 
//primary key defined 		
//		List pkNames = DTPUtil.getPrimaryKeyColumnNames(table.getDbTable());
//		if (pkNames.size() != table.getColumnNames().size()) {
//			return null;
//		}
//		List fkNames = new java.util.ArrayList(assoc1.getReferrerColumnNames()); //clone because we modify by addAll below
//		fkNames.addAll(assoc2.getReferrerColumnNames());
//		if (!CollectionUtil.equalsIgnoreOrder(pkNames, fkNames)) {
//			return null;
//		}
		Association m2m = new Association(this, t1.getName()/*referrerTableName*/, assoc1.getReferencedColumnNames()/*referrerColNames*/
				, t2.getName()/*referencedTableName*/, assoc2.getReferencedColumnNames()/*referencedColNames*/
				, table.getName(), assoc1.getReferrerColumnNames()/*referrerJoinColNames*/, assoc2.getReferrerColumnNames()/*referencedJoinColNames*/);
		m2m.setCustom(false);
		return m2m;
	}

	//---------------------------------------------------
	//---- FileHeader class -----------------------------
	//---------------------------------------------------
	/**
	 * The header of the customization file.
	 */
	private static class FileHeader implements java.io.Serializable
	{
		private static final long serialVersionUID = 1L;
		/**
		 * Should be argument-less because it is used in 
		 * the de-serialization process.
		 */
		public FileHeader() {
			mVersion = FILE_VERSION;
		}
		int mVersion;
	}
	
	private void sortAssociations( List< Association > list ) {
	   Collections.sort( list, new Comparator< Association >() {
	      public int compare( Association lhs, Association rhs ) {
	         // sort by referrer table name first...
	         int test = lhs.getReferrerTableName().compareTo( rhs.getReferrerTableName() );
            if( test != 0 )
               return test;
            // then by referenced table name...
            test = lhs.getReferencedTableName().compareTo( rhs.getReferencedTableName() );
            if( test != 0 )
               return test;
            // if referrer and referenced tables are the same, they should
            // appear next to each other
            return 0;
	      }
	   } );
	}
	public boolean updatePersistenceXml() {
		return mUpdatePersistenceXml;
	}
	public void setUpdatePersistenceXml(boolean updatePersistenceXml) {
		this.mUpdatePersistenceXml = updatePersistenceXml;
	}
}
