/*******************************************************************************
 * Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.tools.db.model;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;
import org.eclipse.persistence.sessions.Connector;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.tools.db.model.handles.MWHandle.NodeReferenceScrubber;
import org.eclipse.persistence.tools.db.model.platformsmodel.DatabasePlatform;
import org.eclipse.persistence.tools.db.model.spi.ExternalDatabase;
import org.eclipse.persistence.tools.db.model.spi.ExternalDatabaseFactory;
import org.eclipse.persistence.tools.db.model.spi.ExternalTableDescription;
import org.eclipse.persistence.tools.db.model.spi.jdbc.JDBCExternalDatabaseFactory;
import org.eclipse.persistence.tools.schemaframework.SchemaManager;
import org.eclipse.persistence.tools.utility.StringTools;
import org.eclipse.persistence.tools.utility.collection.CollectionTools;
import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
import org.eclipse.persistence.tools.utility.node.Node;

/**
 * @version 2.6
 */
@SuppressWarnings("nls")
public final class ELDatabase extends ELModel {

	/** the database platform should never be null */
	private volatile DatabasePlatform databasePlatform;
		public static final String DATABASE_PLATFORM_PROPERTY = "databasePlatform" ;

	private Collection<ELLoginSpec> loginSpecs;
		public static final String LOGIN_SPECS_COLLECTION = "loginSpecs";

	private ELLoginSpecHandle deploymentLoginSpecHandle;
		public static final String DEPLOYMENT_LOGIN_SPEC_PROPERTY = "deploymentLoginSpec";
	private ELLoginSpecHandle developmentLoginSpecHandle;
		public static final String DEVELOPMENT_LOGIN_SPEC_PROPERTY = "developmentLoginSpec";

	private Collection<ELTable> tables;
		public static final String TABLES_COLLECTION = "tables";

	/**
	 * the "external" database that supplies the
	 * "external" tables used to build MWTables
	 */
	private volatile ExternalDatabase externalDatabase;

	/**
	 * transient - java.sql.Driver used to connect to the database;
	 * this field is always null when executing under jdev
	 */
	private volatile Driver driver;

	/**
	 * transient - java.sql.Connection used for collecting meta-data;
	 * this field is always null when executing under jdev
	 */
	private volatile Connection connection;
		// virtual property
		public static final String CONNECTED_PROPERTY = "connected";

	/**
	 * transient - org.eclipse.persistence.tools.schemaframework.SchemaManager
	 * used for generating tables on the database;
	 * this field is always null when executing under jdev
	 */
	private volatile SchemaManager schemaManager;

	private volatile ExternalDatabaseFactory dbFactory;

	/**
	 * these table names are read in by TopLink and are then
	 * used and managed by the IOManager;
	 * DO NOT use them for anything else  ~bjv
	 */
	private Collection<String> tableNames;
		private static final String TABLE_NAMES_COLLECTION = "tableNames";

	/** this setting queried reflectively by the I/O Manager; so don't remove it */
	private static final String SUB_DIRECTORY_NAME = "tables";

	// ********** constructors **********

	public ELDatabase(DatabasePlatform databasePlatform) {
		super(null);
		this.databasePlatform = databasePlatform;
	}


	// ********** initialization **********

	@Override
	protected void checkParent(Node parentNode) {
		// no-op since db is the root node
	}

	/**
	 * initialize transient state
	 */
	@Override
	public void initialize() {
		super.initialize();
		// the tables are not mapped directly
		this.tables = new Vector<ELTable>();
	}

	/**
	 * initialize persistent state
	 */
	@Override
	protected void initialize(Node parent) {
		super.initialize(parent);
		this.loginSpecs = new Vector<ELLoginSpec>();
		// 'deploymentLoginSpec' and 'developmentLoginSpec'
		// are handled directly in #loginSpecRemoved(MWLoginSpec)
		this.deploymentLoginSpecHandle = new ELLoginSpecHandle(this, NodeReferenceScrubber.NULL_INSTANCE);
		this.developmentLoginSpecHandle = new ELLoginSpecHandle(this, NodeReferenceScrubber.NULL_INSTANCE);
		this.tableNames = new HashSet<String>();
	}

	@Override
	public Validator getValidator() {
		return new Validator() {

			@Override
			public void validate() {
			}

			@Override
			public void resume() {
			}

			@Override
			public void pause() {
			}
		};
	}


	// ********** database platform **********

	public DatabasePlatform getDatabasePlatform() {
		return this.databasePlatform;
	}

	public void setDatabasePlatform(DatabasePlatform databasePlatform) {
		if (databasePlatform == null) {
			throw new NullPointerException();
		}
		Object old = this.databasePlatform;
		this.databasePlatform = databasePlatform;
		this.firePropertyChanged(DATABASE_PLATFORM_PROPERTY, old, databasePlatform);
		if (this.attributeValueHasChanged(old, databasePlatform)) {
			this.databasePlatformChanged();
		}
	}

	/**
	 * cascade to the database fields so they can update their types
	 */
	private void databasePlatformChanged() {
		synchronized (this.tables) {
			for (ELTable table : this.tables) {
				table.databasePlatformChanged();
			}
		}
	}


	// ********** login specs **********

	public Iterable<ELLoginSpec> loginSpecs() {
		return new LiveCloneIterable<ELLoginSpec>(this.loginSpecs) {
			@Override
			protected void remove(ELLoginSpec current) {
				ELDatabase.this.removeLoginSpec(current);
			}
		};
	}

	public int loginSpecsSize() {
		return this.loginSpecs.size();
	}

	public ELLoginSpec addLoginSpec(String loginSpecName) {
		this.checkLoginSpecName(loginSpecName);
		return this.addLoginSpec(new ELLoginSpec(this, loginSpecName));
	}

	private ELLoginSpec addLoginSpec(ELLoginSpec loginSpec) {
		this.addItemToCollection(loginSpec, this.loginSpecs, LOGIN_SPECS_COLLECTION);
		if (this.loginSpecs.size() == 1) {
			this.setDeploymentLoginSpec(loginSpec);
			this.setDevelopmentLoginSpec(loginSpec);
		}
		return loginSpec;
	}

	public void removeLoginSpec(ELLoginSpec loginSpec) {
		if (this.removeItemFromCollection(loginSpec, this.loginSpecs, LOGIN_SPECS_COLLECTION)) {
			this.loginSpecRemoved(loginSpec);
		}
	}

	public boolean containsLoginSpecNamed(String loginSpecName) {
		return this.loginSpecNamed(loginSpecName) != null;
	}

	public ELLoginSpec loginSpecNamed(String loginSpecName) {
		synchronized (this.loginSpecs) {
			for (ELLoginSpec spec : this.loginSpecs) {
				if (spec.getName().equals(loginSpecName)) {
					return spec;
				}
			}
		}
		return null;
	}

	public Iterator<String> loginSpecNames() {
		return new TransformationIterator<ELLoginSpec, String>(this.loginSpecs()) {
			@Override
			protected String transform(ELLoginSpec next) {
				return next.getName();
			}
		};
	}


	// ********** deployment login spec **********

	public ELLoginSpec getDeploymentLoginSpec() {
		return this.deploymentLoginSpecHandle.getLoginSpec();
	}

	public void setDeploymentLoginSpec(ELLoginSpec loginSpec) {
		Object old = this.deploymentLoginSpecHandle.getLoginSpec();
		this.deploymentLoginSpecHandle.setLoginSpec(loginSpec);
		this.firePropertyChanged(DEPLOYMENT_LOGIN_SPEC_PROPERTY, old, loginSpec);
	}


	// ********** development login spec **********

	public ELLoginSpec getDevelopmentLoginSpec() {
		return this.developmentLoginSpecHandle.getLoginSpec();
	}

	public void setDevelopmentLoginSpec(ELLoginSpec loginSpec) {
		Object old = this.developmentLoginSpecHandle.getLoginSpec();
		this.developmentLoginSpecHandle.setLoginSpec(loginSpec);
		this.firePropertyChanged(DEVELOPMENT_LOGIN_SPEC_PROPERTY, old, loginSpec);
	}


	// ********** tables **********

	public Iterable<ELTable> tables() {
		return new LiveCloneIterable<ELTable>(this.tables) {
			@Override
			protected void remove(ELTable current) {
				ELDatabase.this.removeTable(current);
			}
		};
	}

	public int tablesSize() {
		return this.tables.size();
	}

	public ELTable addTable(String shortName) {
		return this.addTable(null, shortName);
	}

	public ELTable addTable(String schema, String shortName) {
		return this.addTable(null, schema, shortName);
	}

	public ELTable addTable(String catalog, String schema, String shortName) {
		this.checkTableName(catalog, schema, shortName, null);
		return this.addTable(new ELTable(this, catalog, schema, shortName));
	}

	public ELTable addTableWithFullyQualifiedName(String fullyQualifiedName) {
		Collection<String> strings = CollectionTools.collection(fullyQualifiedName.split("\\."));
   		CollectionTools.removeAllOccurrences(strings, StringTools.EMPTY_STRING);
   		String[] parsedName = strings.toArray(new String[strings.size()]);
   		if (parsedName.length == 3) {
   			return addTable(parsedName[0], parsedName[1], parsedName[2]);
   		}
   		else if (parsedName.length == 2) {
   			return addTable(parsedName[0], parsedName[1]);
   		}
   		else {
  			return addTable(parsedName[0]);
  		}
   	}

	private ELTable addTable(ELTable table) {
		this.addItemToCollection(table, this.tables, TABLES_COLLECTION);
		return table;
	}

	public void removeTable(ELTable table) {
		this.removeNodeFromCollection(table, this.tables, TABLES_COLLECTION);
	}

	public boolean containsTableNamed(String catalog, String schema, String shortName) {
		return this.tableNamed(catalog, schema, shortName) != null;
	}

	public ELTable tableNamed(String catalog, String schema, String shortName) {
		synchronized (this.tables) {
			for (ELTable table : this.tables) {
				if (table.nameMatches(catalog, schema, shortName)) {
					return table;
				}
			}
		}
		return null;
	}

	public boolean containsTableNamedIgnoreCase(String catalog, String schema, String shortName) {
		return this.tableNamedIgnoreCase(catalog, schema, shortName) != null;
	}

	public ELTable tableNamedIgnoreCase(String catalog, String schema, String shortName) {
		synchronized (this.tables) {
			for (ELTable table : this.tables) {
				if (table.nameMatchesIgnoreCase(catalog, schema, shortName)) {
					return table;
				}
			}
		}
		return null;
	}

	public boolean containsTableNamed(String qualifiedName) {
		return this.tableNamed(qualifiedName) != null;
	}

	public ELTable tableNamed(String qualifiedName) {
		synchronized (this.tables) {
			for (ELTable table : this.tables) {
				if (table.qualifiedName().equals(qualifiedName)) {
					return table;
				}
			}
		}
		return null;
	}

	/**
	 * used to prevent adding a duplicate table
	 */
	public Iterator<String> tableNames() {
		return new TransformationIterator<ELTable, String>(this.tables()) {
			@Override
			protected String transform(ELTable next) {
				return next.getName();
			}
		};
	}

	public ELColumn columnNamed(String qualifiedName) {
		ELTable table = this.tableNamed(ELColumn.parseTableNameFromQualifiedName(qualifiedName));
		if (table == null) {
			return null;
		}
		return table.columnNamed(ELColumn.parseColumnNameFromQualifiedName(qualifiedName));
	}


	// ********** external database **********

	/**
	 * PRIVATE - no one should need direct access to the external database
	 */
	public ExternalDatabase getExternalDatabase() {
		if (this.externalDatabase == null) {
			this.externalDatabase = this.buildExternalDatabase();
		}
		return this.externalDatabase;
	}

	private ExternalDatabase buildExternalDatabase() {
		// when executing under jdev, the connection will be null
		return this.externalDatabaseFactory().buildDatabase(this.connection);
	}

	private ExternalDatabaseFactory getExternalDatabaseFactory() {
		if (this.dbFactory == null) {
			this.dbFactory = new JDBCExternalDatabaseFactory();
		}

		return this.dbFactory;
	}


	// ********** connection **********

	/**
	 * this method is not called when executing under jdev
	 */
	public boolean isConnected() {
		return this.connection != null;
	}


	// ********** schema manager **********

	/**
	 * call #isConnected()/#login() before calling this method or you
	 * might get an IllegalStateException;
	 * this method is not called when executing under jdev
	 */
	private SchemaManager getSchemaManager() {
		if (this.schemaManager == null) {
			throw new IllegalStateException("not connected");
		}
		return this.schemaManager;
	}


	// ********** queries **********

	/**
	 * the external database factory is supplied by client code
	 */
	private ExternalDatabaseFactory externalDatabaseFactory() {
		return getExternalDatabaseFactory();
	}

	boolean supportsIdentityClause() {
		return this.databasePlatform.supportsIdentityClause();
	}


	// ********** miscellaneous behavior **********

	/**
	 * 'connected' is a virtual property
	 */
	@Override
	protected void addTransientAspectNamesTo(Set<String> transientAspectNames) {
		super.addTransientAspectNamesTo(transientAspectNames);
		transientAspectNames.add(CONNECTED_PROPERTY);
	}

	/**
	 * disallow duplicate login info names
	 */
	void checkLoginSpecName(String loginSpecName) {
		if ((loginSpecName == null) || (loginSpecName.length() == 0)) {
			throw new IllegalArgumentException();
		}
		if (this.containsLoginSpecNamed(loginSpecName)) {
			throw new IllegalArgumentException("duplicate login spec name: " + loginSpecName);
		}
	}

	/**
	 * disallow duplicate table names
	 */
	void checkTableName(String catalog, String schema, String shortName, ELTable table) {
		this.checkTableNameQualifier(catalog);
		this.checkTableNameQualifier(schema);
		if ((shortName == null) || (shortName.length() == 0)) {
			throw new IllegalArgumentException();
		}
		ELTable match = this.tableNamed(catalog, schema, shortName);
		if (match != null) {
			throw new IllegalArgumentException("duplicate table name: " + match.qualifiedName());
		}
		ELTable matchIgnoreCase = this.tableNamedIgnoreCase(catalog, schema, shortName);
		if ((matchIgnoreCase != null) && (matchIgnoreCase != table)) {
			throw new IllegalArgumentException("duplicate table name: " + matchIgnoreCase.qualifiedName());
		}
	}

	/**
	 * table qualifiers must be null or non-empty
	 */
	private void checkTableNameQualifier(String qualifier) {
		if (qualifier == null) {
			return;
		}
		if (qualifier.length() == 0) {
			throw new IllegalArgumentException();
		}
	}


	// ********** model synchronization **********

	@Override
	protected void addChildrenTo(List<Node> children) {
		super.addChildrenTo(children);
		synchronized (this.loginSpecs) { children.addAll(this.loginSpecs); }
		children.add(this.deploymentLoginSpecHandle);
		children.add(this.developmentLoginSpecHandle);
		synchronized (this.tables) { children.addAll(this.tables); }
	}

	private void loginSpecRemoved(ELLoginSpec loginSpec) {
		if (this.getDeploymentLoginSpec() == loginSpec) {
			this.setDeploymentLoginSpec(null);
		}
		if (this.getDevelopmentLoginSpec() == loginSpec) {
			this.setDevelopmentLoginSpec(null);
		}
	}

	/**
	 * performance tuning: override this method and assume
	 * the database's descendants have NO references (handles)
	 * to any models other than other descendants of the database
	 */
	@Override
	public void nodeRemoved(Node node) {
		if (node.isDescendantOf(this)) {
			super.nodeRemoved(node);
		}
	}

	/**
	 * performance tuning: override this method and assume
	 * the database's descendants have NO references (handles)
	 * to any models other than other descendants of the database
	 */
	@Override
	public void nodeRenamed(Node node) {
		if (node.isDescendantOf(this)) {
			super.nodeRenamed(node);
			// we handle a renamed table directly in #tableRenamed()
		}
	}

	// ********** login/logout **********

	/**
	 * you must log in before accessing the connection or
	 * schema manager;
	 * we instantiate and connect the JDBC Driver manually, ignoring
	 * the stupid JDBC DriverManager;
	 * this method is not called when executing under jdev
	 */
	public void login() throws SQLException, ClassNotFoundException {
		if (this.isConnected()) {
			throw new IllegalStateException("already connected");
		}
		ELLoginSpec loginSpec = this.getDevelopmentLoginSpec();
		if (loginSpec == null) {
			throw new IllegalStateException("missing development login spec");
		}

		try {
			this.driver = loginSpec.buildDriver();
		} catch (InstantiationException ex) {
			throw new RuntimeException(ex);
		} catch (IllegalAccessException ex) {
			throw new RuntimeException(ex);
		}

		String url = loginSpec.getURL();
		if ((url == null) || (url.length() == 0)) {
			throw new IllegalStateException("missing database URL");
		}

		// store the user name and password in a dictionary
		Properties props = new Properties();
		String userName = loginSpec.getUserName();
		if (userName != null) {
			props.put("user", userName);
		}
		String password = loginSpec.getPassword();
		if (password != null) {
			props.put("password", password);
		}

		this.connection = this.driver.connect(url, props);

		// once we are connected we can build the schema manager
		this.schemaManager = this.buildSchemaManager();
		this.firePropertyChanged(CONNECTED_PROPERTY, false, true);
	}

	/**
	 * disconnect from the database and clear out any state that relies
	 * on the connection;
	 * this method is not called when executing under jdev
	 */
	public void logout() throws SQLException {
		if ( ! this.isConnected()) {
			throw new IllegalStateException("not connected");
		}
		this.connection.close();
		this.schemaManager = null;
		this.connection = null;
		this.driver = null;
		this.externalDatabase = null;
		this.firePropertyChanged(CONNECTED_PROPERTY, true, false);
	}

	private SchemaManager buildSchemaManager() {
		return new SchemaManager(this.buildRuntimeDatabaseSession());
	}

	/**
	 * this db session will use the *development* login spec;
	 * this method is not called when executing under jdev
	 */
	private DatabaseSession buildRuntimeDatabaseSession() {
		DatabaseSession session = this.buildRuntimeProject().createDatabaseSession();
		session.dontLogMessages();
		session.login();
		return session;
	}

	/**
	 * this project will use the *development* login spec
	 * this method is not called when executing under jdev
	 */
	private Project buildRuntimeProject() {
		return new Project(this.getDevelopmentLoginSpec().buildDevelopmentRuntimeDatabaseLogin());
	}

	/**
	 * build a connector that will use the database's connection;
	 * this method is not called when executing under jdev
	 */
	Connector buildRuntimeConnector() {
		return new LocalConnectorAdapter(this.connection);
	}


	// ********** table importing/refreshing **********

	/**
	 * Returns the "catalog" names from the current database.
	 * @see java.sql.DatabaseMetaData#getCatalogs()
	 */
	public Iterator<String> catalogNames() {
		return new ArrayIterator<String>(this.getExternalDatabase().getCatalogNames());
	}

	/**
	 * Returns the "schema" names from the current database.
	 * @see java.sql.DatabaseMetaData#getSchemas()
	 */
	public Iterator<String> schemaNames() {
		if (!getDatabasePlatform().getName().equals("MySQL")) {
			return new ArrayIterator<String>(this.getExternalDatabase().getSchemaNames());
		} else {
			return new ArrayIterator<String>(this.getExternalDatabase().getCatalogNames());
		}
	}

	/**
	 * Returns the "table type" names from the current database.
	 * @see java.sql.DatabaseMetaData#getTableTypes()
	 */
	public Iterator<String> tableTypeNames() {
		return new ArrayIterator<String>(this.getExternalDatabase().getTableTypeNames());
	}

	/**
	 * Returns the "external" table descriptions corresponding to the specified
	 * search criteria; these can then be used to import and/or refresh tables
	 * @see #externalTableDescriptions()
	 * @see #importQualifiedTablesFor(java.util.Collection)
	 * @see #importUnqualifiedTablesFor(java.util.Collection)
	 * @see #refreshQualifiedTablesFor(java.util.Collection)
	 * @see java.sql.DatabaseMetaData#getTables(String, String, String, String[])
	 */
	public Iterator<ExternalTableDescription> externalTableDescriptions(String catalog, String schemaPattern, String tableNamePattern, String[] types) {
		return new ArrayIterator<ExternalTableDescription>(
			this.getExternalDatabase().getTableDescriptions(catalog, schemaPattern, tableNamePattern, types)
		);
	}

	/**
	 * Returns the all the "external" table descriptions;
	 * these can then be used to import and/or refresh tables
	 * @see #externalTableDescriptions(String, String, String, String[])
	 * @see #importQualifiedTablesFor(java.util.Collection)
	 * @see #importUnqualifiedTablesFor(java.util.Collection)
	 * @see #refreshQualifiedTablesFor(java.util.Collection)
	 */
	public Iterator<ExternalTableDescription> externalTableDescriptions() {
		return new ArrayIterator<ExternalTableDescription>(
			this.getExternalDatabase().getTableDescriptions()
		);
	}

	/**
	 * import the tables corresponding to the specified
	 * "external" table descriptions, using their fully-qualified names;
	 * this is a two-step process: all the fields must be in place before
	 * we can build or refresh the references
	 */
	public void importQualifiedTablesFor(Collection<ExternalTableDescription> externalTableDescriptions) {
		for (Iterator<ExternalTableDescription> stream = externalTableDescriptions.iterator(); stream.hasNext(); ) {
			ExternalTableDescription externalTableDescription = stream.next();
			this.qualifiedTableFor(externalTableDescription).refreshColumns(externalTableDescription.getTable());
		}
		for (Iterator<ExternalTableDescription> stream = externalTableDescriptions.iterator(); stream.hasNext(); ) {
			ExternalTableDescription externalTableDescription = stream.next();
			this.qualifiedTableFor(externalTableDescription).refreshReferences(externalTableDescription.getTable());
		}
	}

	/**
	 * refresh the tables corresponding to the specified "external" table descriptions, using their fully
	 * qualified names; this is a two-step process: all the fields must be in place before
	 * we can refresh the references;
	 * we want different behavior here because we don't want to
	 * create them if they don't exist and we must handle unqualified tables
	 */
	public void refreshQualifiedTablesFor(Collection<ExternalTableDescription> externalTableDescriptions) {
		for (Iterator<ExternalTableDescription> stream = externalTableDescriptions.iterator(); stream.hasNext(); ) {
			ExternalTableDescription externalTableDescription = stream.next();
			ELTable tableToRefresh = this.tableNamed(externalTableDescription.getQualifiedName());
			if (tableToRefresh == null) {
				// the table's name may be unqualified
				tableToRefresh = this.tableNamed(externalTableDescription.getName());
			}
			if (tableToRefresh != null) {
				tableToRefresh.refreshColumns(externalTableDescription.getTable());
			}
		}
		for (Iterator<ExternalTableDescription> stream = externalTableDescriptions.iterator(); stream.hasNext(); ) {
			ExternalTableDescription externalTableDescription = stream.next();
			ELTable tableToRefresh = this.tableNamed(externalTableDescription.getQualifiedName());
			if (tableToRefresh == null) {
				// the table's name may be unqualified
				tableToRefresh = this.tableNamed(externalTableDescription.getName());
			}
			if (tableToRefresh != null) {
				tableToRefresh.refreshReferences(externalTableDescription.getTable());
			}
		}
	}

	/**
	 * Returns the table corresponding to the specified "external" table description,
	 * creating it if necessary; use the table's fully-qualified name
	 */
	private ELTable qualifiedTableFor(ExternalTableDescription externalTableDescription) {
		if (getDatabasePlatform().getName().equals("MySQL")) {
			return this.tableNamedForImport(null, externalTableDescription.getCatalogName(), externalTableDescription.getName());
		} else {
			return this.tableNamedForImport(externalTableDescription.getCatalogName(), externalTableDescription.getSchemaName(), externalTableDescription.getName());
		}
	}

	/**
	 * Returns the requested table, creating it if necessary
	 */
	private ELTable tableNamedForImport(String catalog, String schema, String shortName) {
		ELTable table = this.tableNamed(catalog, schema, shortName);
		if (table == null) {
			table = this.addTable(catalog, schema, shortName);
		}
		return table;
	}

	/**
	 * import and/or refresh the tables corresponding to the specified
	 * "external" table descriptions, using their "short" names;
	 * this is a two-step process: all the fields must be in place before
	 * we can build or refresh the references
	 */
	public void importUnqualifiedTablesFor(Collection<ExternalTableDescription> externalTableDescriptions) {
		for (Iterator<ExternalTableDescription> stream = externalTableDescriptions.iterator(); stream.hasNext(); ) {
			ExternalTableDescription externalTableDescription = stream.next();
			this.unqualifiedTableFor(externalTableDescription).refreshColumns(externalTableDescription.getTable());
		}
		for (Iterator<ExternalTableDescription> stream = externalTableDescriptions.iterator(); stream.hasNext(); ) {
			ExternalTableDescription externalTableDescription = stream.next();
			this.unqualifiedTableFor(externalTableDescription).refreshReferences(externalTableDescription.getTable());
		}
	}

	/**
	 * Returns the table corresponding to the specified "external" table description,
	 * creating it if necessary; use the table's "short" name
	 */
	private ELTable unqualifiedTableFor(ExternalTableDescription externalTableDescription) {
		return this.tableNamedForImport(null, null, externalTableDescription.getName());
	}

	// ********** printing and displaying **********

	public void toString(StringBuffer sb) {
		sb.append(this.getDatabasePlatform().getName());
		sb.append(" : ");
		sb.append(this.tables.size());
		sb.append(" tables");
	}

	@Override
	public String displayString() {
		StringBuffer sb = new StringBuffer();
		sb.append("Database (");
		sb.append(this.getDatabasePlatform().getName());
		sb.append(")");
		return sb.toString();
	}


	// ********** SubComponentContainer implementation **********

	public Iterable projectSubFileComponents() {
		return this.tables();
	}

	public void setProjectSubFileComponents(Collection subComponents) {
		this.tables = subComponents;
	}

	public Iterator originalProjectSubFileComponentNames() {
		return this.tableNames.iterator();
	}

	public void setOriginalProjectSubFileComponentNames(Collection originalSubComponentNames) {
		this.tableNames = originalSubComponentNames;
	}

	public boolean hasChangedMainProjectSaveFile() {
		if (this.isDirty()) {
			// the database itself is dirty
			return true;
		}
		for (Iterator stream = this.children(); stream.hasNext(); ) {
			if (this.childHasChangedTheProjectSaveFile(stream.next())) {
				return true;
			}
		}
		// the tables might be dirty
		return false;
	}

	/**
	 * Returns whether the specified child of the database is dirty AND
	 * is written to the .mwp file
	 */
	private boolean childHasChangedTheProjectSaveFile(Object child) {
		if (this.tables.contains(child)) {
			// tables are written to separate files
			return false;
		}
		// the child is NOT a table,
		// so all of its state is written to the .mwp file
		return ((Node) child).isDirtyBranch();
	}

	// ********** inner classes **********

	/**
	 * Adapt the database to the TopLink run-time Connector interface.
	 */
	private static class LocalConnectorAdapter implements Connector {
		private Connection connection;
		LocalConnectorAdapter(Connection connection) {
			super();
			this.connection = connection;
		}
		/** this is the only method of note */
		@Override
		public Connection connect(Properties properties, Session session) {
			return this.connection;
		}
		@Override
		public Object clone() {
			try {
				return super.clone();
			} catch (CloneNotSupportedException ex) {
				throw new InternalError();
			}
		}
		@Override
		public String getConnectionDetails() {
			return "MWDatabase.LocalConnectorAdapter";
		}
		@Override
		public void toString(PrintWriter writer) {
			writer.print(this.getConnectionDetails());
		}
	}
}