/*******************************************************************************
 * Copyright (c) 2006, 2011 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.db.tests.internal.platforms;

import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import junit.framework.TestCase;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.datatools.connectivity.ConnectionProfileException;
import org.eclipse.datatools.connectivity.IConnectionProfile;
import org.eclipse.datatools.connectivity.ProfileManager;
import org.eclipse.datatools.connectivity.drivers.IDriverMgmtConstants;
import org.eclipse.datatools.connectivity.drivers.IPropertySet;
import org.eclipse.datatools.connectivity.drivers.PropertySetImpl;
import org.eclipse.datatools.connectivity.drivers.XMLFileManager;
import org.eclipse.datatools.connectivity.drivers.jdbc.IJDBCDriverDefinitionConstants;
import org.eclipse.datatools.connectivity.internal.ConnectivityPlugin;
import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObject;
import org.eclipse.jpt.common.utility.IndentingPrintWriter;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.common.utility.internal.ReflectionTools;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.iterators.ResultSetIterator;
import org.eclipse.jpt.jpa.db.Catalog;
import org.eclipse.jpt.jpa.db.Column;
import org.eclipse.jpt.jpa.db.ConnectionListener;
import org.eclipse.jpt.jpa.db.ConnectionProfile;
import org.eclipse.jpt.jpa.db.ConnectionProfileFactory;
import org.eclipse.jpt.jpa.db.ConnectionProfileListener;
import org.eclipse.jpt.jpa.db.Database;
import org.eclipse.jpt.jpa.db.DatabaseIdentifierAdapter;
import org.eclipse.jpt.jpa.db.ForeignKey;
import org.eclipse.jpt.jpa.db.JptJpaDbPlugin;
import org.eclipse.jpt.jpa.db.Schema;
import org.eclipse.jpt.jpa.db.SchemaContainer;
import org.eclipse.jpt.jpa.db.Sequence;
import org.eclipse.jpt.jpa.db.Table;
import org.eclipse.jpt.jpa.db.tests.internal.JptJpaDbTestsPlugin;

/**
 * Base class for testing DTP wrappers on various databases.
 */
@SuppressWarnings("nls")
public abstract class DTPPlatformTests extends TestCase {

	/**
	 * The platform properties are loaded from a Java properties file in the
	 * 'org.eclipse.jpt.jpa.db.tests/config' directory. Each database platform has
	 * its own properties file (e.g. 'derby.properties').
	 */
	private Properties platformProperties;

	/**
	 * This is the Dali connection profile wrapper.
	 */
	protected ConnectionProfile connectionProfile;


	// ********** constants **********

	private static final String PLATFORM_CONFIG_DIRECTORY = "config";

	private static final String DB_USER_ID_PROPERTY = "userID";
		private static final String DB_USER_ID_DEFAULT = "user";

	private static final String DB_PASSWORD_PROPERTY = "password";
		private static final String DB_PASSWORD_DEFAULT = "";

	private static final String DB_DRIVER_JARS_PROPERTY = "jars";
		// required - no default

	private static final String DB_URL_PROPERTY = "url";
		// required - no default



	// ********** constructor **********

	protected DTPPlatformTests(String name) {
		super(name);
	}


	// ********** set-up/tear-down **********

	@Override
	protected void setUp() throws Exception {
		super.setUp();

		this.platformProperties = this.loadPlatformProperties();
		this.buildDTPDriverDefinitionFile();
		this.buildDTPConnectionProfile();
		this.connectionProfile = this.getConnectionProfileFactory().buildConnectionProfile(this.getProfileName(), DatabaseIdentifierAdapter.Default.instance());
	}

	@Override
	protected void tearDown() throws Exception {
		this.connectionProfile = null;
		this.platformProperties = null;

		super.tearDown();
	}

	// ***** platform properties file
	private Properties loadPlatformProperties() throws IOException {
		Properties p = new Properties();
		p.load(this.buildPlatformPropertiesFileURL().openStream());
		return p;
	}

	private URL buildPlatformPropertiesFileURL() {
		return Platform.getBundle(this.getTestPluginBundleID()).getEntry(this.getPlatformPropertiesFilePath());
	}

	private String getTestPluginBundleID() {
		return JptJpaDbTestsPlugin.BUNDLE_ID;
	}

	private String getPlatformPropertiesFilePath() {
		return this.getPlatformPropertiesDirectoryName() + '/' + this.getPlatformPropertiesFileName();
	}

	private String getPlatformPropertiesDirectoryName() {
		return PLATFORM_CONFIG_DIRECTORY;
	}

	/**
	 * Each database platform has a separate properties file in the 'config'
	 * directory that must be customized by whomever is executing the tests.
	 */
	protected abstract String getPlatformPropertiesFileName();

	// ***** driver definition file
	private void buildDTPDriverDefinitionFile() throws CoreException {
		XMLFileManager.setStorageLocation(this.getDTPDriverDefinitionLocation());
		XMLFileManager.setFileName(this.getDTPDriverFileName());

		IPropertySet[] sets = XMLFileManager.loadPropertySets();
		for (IPropertySet set : sets) {
			if (set.getID().equals(this.getDriverDefinitionID())) {
				return;  // property sets live across tests
			}
		}

		XMLFileManager.saveNamedPropertySet(this.buildDTPDriverDefinitionPropertySets());

		// verify the file was created:
		File driverDefinitioneFile = this.getDTPDriverDefinitionLocation().append(this.getDTPDriverFileName()).toFile();
		assertTrue(driverDefinitioneFile.exists());
	}

	private IPath getDTPDriverDefinitionLocation() {
		return ConnectivityPlugin.getDefault().getStateLocation();
	}

	private String getDTPDriverFileName() {
		return IDriverMgmtConstants.DRIVER_FILE;
	}

	private IPropertySet[] buildDTPDriverDefinitionPropertySets() {
		IPropertySet[] propertySets = new IPropertySet[1];
		PropertySetImpl propertySet = new PropertySetImpl(this.getDriverName(), this.getDriverDefinitionID());
		propertySet.setProperties(this.getDriverDefinitionID(), this.buildDTPDriverDefinitionProperties());
		propertySets[0] = propertySet;
		return propertySets;
	}

	protected abstract String getDriverName();

	protected abstract String getDriverDefinitionID();

	private Properties buildDTPDriverDefinitionProperties() {
		Properties p = new Properties();
		p.setProperty(ConnectionProfile.DRIVER_DEFINITION_TYPE_PROP_ID, this.getDriverDefinitionType());
		p.setProperty(ConnectionProfile.DRIVER_JAR_LIST_PROP_ID, this.getJDBCDriverJarList());
		p.setProperty(IJDBCDriverDefinitionConstants.DATABASE_VENDOR_PROP_ID, this.getDatabaseVendor());
		p.setProperty(IJDBCDriverDefinitionConstants.DATABASE_VERSION_PROP_ID, this.getDatabaseVersion());
		p.setProperty(IJDBCDriverDefinitionConstants.DRIVER_CLASS_PROP_ID, this.getDriverClass());
		p.setProperty(IJDBCDriverDefinitionConstants.URL_PROP_ID, this.getJDBCURL());
		p.setProperty(IJDBCDriverDefinitionConstants.USERNAME_PROP_ID, this.getUserID());
		p.setProperty(IJDBCDriverDefinitionConstants.PASSWORD_PROP_ID, this.getPassword());
		return p;
	}

	protected abstract String getDriverDefinitionType();

	/**
	 * The JAR list is workspace-specific and is set in the properties file.
	 */
	private String getJDBCDriverJarList() {
		return this.getRequiredPlatformProperty(DB_DRIVER_JARS_PROPERTY);
	}

	protected abstract String getDatabaseVendor();

	protected abstract String getDatabaseVersion();

	protected abstract String getDriverClass();

	/**
	 * The database URL is workspace-specific and is set in the properties file
	 * for some databases.
	 */
	private String getJDBCURL() {
		return this.platformProperties.getProperty(DB_URL_PROPERTY, this.getDefaultJDBCURL());
	}

	protected String getDefaultJDBCURL() {
		return "";
	}

	/**
	 * The user ID is optional and can be set in the properties file.
	 */
	protected String getUserID() {
		return this.platformProperties.getProperty(DB_USER_ID_PROPERTY, DB_USER_ID_DEFAULT);
	}

	/**
	 * The password is optional and can be set in the properties file.
	 */
	private String getPassword() {
		return this.platformProperties.getProperty(DB_PASSWORD_PROPERTY, DB_PASSWORD_DEFAULT);
	}

	// ***** DTP connection profile
	private void buildDTPConnectionProfile() throws ConnectionProfileException {
		if (this.getDTPProfileManager().getProfileByName(this.getProfileName()) != null) {
			return;  // profiles live across tests
		}
		this.createProfile(this.getProfileName());
		assertNotNull(this.getDTPProfileManager().getProfileByName(this.getProfileName()));
	}

	protected void createProfile(String profileName) throws ConnectionProfileException {
		this.getDTPProfileManager().createProfile(
				profileName,
				this.getProfileDescription(),
				this.getProviderID(),
				this.buildDTPConnectionProfileProperties()
		);
	}

	protected abstract String getProfileName();

	protected abstract String getProfileDescription();

	protected String getProviderID() {
		return ConnectionProfile.CONNECTION_PROFILE_TYPE;
	}
	 
	protected Properties buildDTPConnectionProfileProperties() {
		Properties p = new Properties();
		p.setProperty(IJDBCDriverDefinitionConstants.USERNAME_PROP_ID, this.getUserID());
		p.setProperty(IJDBCDriverDefinitionConstants.PASSWORD_PROP_ID, this.getPassword());
		p.setProperty(ConnectionProfile.DRIVER_DEFINITION_PROP_ID, this.getDriverDefinitionID());

		p.setProperty(IJDBCDriverDefinitionConstants.DRIVER_CLASS_PROP_ID, this.getDriverClass());
		p.setProperty(IJDBCDriverDefinitionConstants.URL_PROP_ID, this.getJDBCURL());
		p.setProperty(IJDBCDriverDefinitionConstants.DATABASE_VENDOR_PROP_ID, this.getDatabaseVendor());
		p.setProperty(IJDBCDriverDefinitionConstants.DATABASE_VERSION_PROP_ID, this.getDatabaseVersion());

		p.setProperty(ConnectionProfile.DATABASE_SAVE_PWD_PROP_ID, this.passwordIsSaved());
		return p;
	}

	private String passwordIsSaved() {
		return "true";
	}


	// ********** tests **********

	public void testConnectionProfileListener() throws ConnectionProfileException {
		TestConnectionProfileListener listener = new TestConnectionProfileListener();
		this.getConnectionProfileFactory().addConnectionProfileListener(listener);

		String cpName1 = this.getProfileName() + "1";
		this.createProfile(cpName1);
		IConnectionProfile dtpCP = this.getDTPProfileManager().getProfileByName(cpName1);
		assertNotNull(dtpCP);

		assertEquals(cpName1, listener.addedName);
		listener.clear();

		String cpName2 = this.getProfileName() + "2";
		this.getDTPProfileManager().modifyProfile(dtpCP, cpName2, null);
		assertEquals(cpName1, listener.renamedOldName);
		assertEquals(cpName2, listener.renamedNewName);
		listener.clear();

		ConnectionProfile cp = this.getConnectionProfileFactory().buildConnectionProfile(cpName2);
		assertNotNull(cp);

		this.getDTPProfileManager().deleteProfile(dtpCP);
		assertEquals(cpName2, listener.removedName);
		listener.clear();

		cp = this.getConnectionProfileFactory().buildConnectionProfile(cpName2);
		assertNull(cp);

		this.getConnectionProfileFactory().removeConnectionProfileListener(listener);
	}

	public void testName() {
		assertEquals(this.getProfileName(), this.connectionProfile.getName());
	}

	public void testConnection() throws Exception {
		assertTrue(this.connectionProfile.isInactive());
		assertTrue(this.connectionProfile.isDisconnected());
		this.connectionProfile.connect();
		assertTrue(this.connectionProfile.isActive());
		assertTrue(this.connectionProfile.isConnected());

		this.verifyDatabaseVersionNumber();
		this.verifyDatabaseVendor();
		this.verifyDatabaseContent();

		this.connectionProfile.disconnect();
		assertTrue(this.connectionProfile.isInactive());
		assertTrue(this.connectionProfile.isDisconnected());
	}

	private void verifyDatabaseVersionNumber() {
		Database database = this.connectionProfile.getDatabase();
		assertNotNull(database);

		String actual = database.getVersion();
		String expected = this.getDatabaseVersion();
		String errorMessage = "expected: " + expected + " - actual: " + actual;
		// partial match is good enough
		assertTrue(errorMessage, actual.indexOf(expected) != -1);
	}

	private void verifyDatabaseVendor() {
		Database database = this.connectionProfile.getDatabase();
		String actual = database.getVendorName();
		String expected = this.getDatabaseVendor();
		assertEquals(expected, actual);
	}

	private void verifyDatabaseContent() {
		Database database = this.connectionProfile.getDatabase();
		assertTrue(database.getSchemataSize() >= 0);

		Schema schema = database.getDefaultSchema();
		if (schema != null) {
			if (schema.getTablesSize() > 0) {
				Table table = schema.getTables().iterator().next();
				assertTrue(table.getColumnsSize() >= 0);
				assertTrue(table.getPrimaryKeyColumnsSize() >= 0);
				assertTrue(table.getForeignKeysSize() >= 0);
			}
		}
	}

	protected abstract boolean executeOfflineTests();

	public final void testOffline() {
		if ( ! this.executeOfflineTests()) {
			return;
		}
		if ( ! this.connectionProfile.supportsWorkOfflineMode()) {
			return;
		}

		this.prepareForOfflineWork();

		IStatus status = this.connectionProfile.workOffline();
		assertTrue(status.isOK());
		assertTrue(this.connectionProfile.isActive());
		assertTrue(this.connectionProfile.isWorkingOffline());

		this.connectionProfile.disconnect();
		assertTrue(this.connectionProfile.isInactive());
		assertTrue(this.connectionProfile.isDisconnected());
	}

	protected void prepareForOfflineWork() {
		if ( ! this.connectionProfile.canWorkOffline()) {
			this.connectionProfile.connect();
			IStatus status = this.connectionProfile.saveWorkOfflineData();
			assertTrue(status.isOK());
			this.connectionProfile.disconnect();
			assertTrue(this.connectionProfile.canWorkOffline());
		}
	}

	public void testConnectionListenerConnect() {
		assertTrue(this.connectionProfileHasNoListeners());
		TestConnectionListener listener = new TestConnectionListener();
		this.connectionProfile.addConnectionListener(listener);
		assertTrue(this.connectionProfileHasAnyListeners());

		this.connectionProfile.connect();
		assertSame(this.connectionProfile, listener.openedProfile);
		listener.clear();

		this.connectionProfile.disconnect();
		assertSame(this.connectionProfile, listener.okToCloseProfile);
		assertSame(this.connectionProfile, listener.aboutToCloseProfile);
		assertSame(this.connectionProfile, listener.closedProfile);

		this.connectionProfile.removeConnectionListener(listener);
		assertTrue(this.connectionProfileHasNoListeners());
	}

	public final void testConnectionListenerOffline() {
		if ( ! this.executeOfflineTests()) {
			return;
		}
		TestConnectionListener listener = new TestConnectionListener();
		this.connectionProfile.addConnectionListener(listener);

		this.prepareForOfflineWork();
		listener.clear();

		this.connectionProfile.workOffline();
		assertSame(this.connectionProfile, listener.openedProfile);
		listener.clear();

		this.connectionProfile.disconnect();
		assertSame(this.connectionProfile, listener.okToCloseProfile);
		assertSame(this.connectionProfile, listener.aboutToCloseProfile);
		assertSame(this.connectionProfile, listener.closedProfile);
		listener.clear();

		this.connectionProfile.removeConnectionListener(listener);
	}

	public void testConnectionListenerDatabase() {
		this.connectionProfile.connect();
		TestConnectionListener listener = new TestConnectionListener();
		this.connectionProfile.addConnectionListener(listener);

		((ICatalogObject) this.getDTPDatabase()).refresh();
		assertSame(this.connectionProfile.getDatabase(), listener.changedDatabase);

		this.connectionProfile.removeConnectionListener(listener);
		this.connectionProfile.disconnect();
	}

	public void testConnectionListenerCatalog() {
		this.connectionProfile.connect();
		if ( ! this.connectionProfile.getDatabase().supportsCatalogs()) {
			this.connectionProfile.disconnect();
			return;
		}
			
		TestConnectionListener listener = new TestConnectionListener();
		this.connectionProfile.addConnectionListener(listener);

		// take the first catalog
		org.eclipse.datatools.modelbase.sql.schema.Catalog dtpCatalog = this.getFirstDTPCatalog();
		Catalog catalog = this.getCatalogNamed(dtpCatalog.getName());
		((ICatalogObject) dtpCatalog).refresh();
		assertSame(catalog, listener.changedCatalog);

		this.connectionProfile.removeConnectionListener(listener);
		this.connectionProfile.disconnect();
	}

	public void testConnectionListenerSchema() {
		this.connectionProfile.connect();
		TestConnectionListener listener = new TestConnectionListener();
		this.connectionProfile.addConnectionListener(listener);

		List<org.eclipse.datatools.modelbase.sql.schema.Catalog> dtpCatalogs = this.getDTPCatalogs();
		org.eclipse.datatools.modelbase.sql.schema.Catalog dtpCatalog = null;
		org.eclipse.datatools.modelbase.sql.schema.Schema dtpSchema = null;
		Schema schema = null;
		if (this.connectionProfile.getDatabase().supportsCatalogs()) {
			dtpCatalog = dtpCatalogs.get(0);
			dtpSchema = (org.eclipse.datatools.modelbase.sql.schema.Schema) dtpCatalog.getSchemas().get(0);
			schema = this.getCatalogNamed(dtpCatalog.getName()).getSchemaNamed(dtpSchema.getName());
		} else {
			if (dtpCatalogs.isEmpty()) {
				dtpSchema = (org.eclipse.datatools.modelbase.sql.schema.Schema) this.getDTPDatabase().getSchemas().get(0);
				schema = this.connectionProfile.getDatabase().getSchemaNamed(dtpSchema.getName());
			} else {
				dtpCatalog = dtpCatalogs.get(0);  // should be the "virtual" catalog
				assertEquals("", dtpCatalog.getName());
				dtpSchema = (org.eclipse.datatools.modelbase.sql.schema.Schema) dtpCatalog.getSchemas().get(0);
				// the schemata are held directly by the database in this situation
				schema = this.getDatabase().getSchemaNamed(dtpSchema.getName());
			}
		}
		assertTrue(schema.getTablesSize() >= 0);  // force tables to be loaded
		((ICatalogObject) dtpSchema).refresh();
		assertSame(schema, listener.changedSchema);

		this.connectionProfile.removeConnectionListener(listener);
		this.connectionProfile.disconnect();
	}

	public void testSupportsCatalogs() {
		this.connectionProfile.connect();
		TestConnectionListener listener = new TestConnectionListener();
		this.connectionProfile.addConnectionListener(listener);

		boolean supportsCatalogs = this.supportsCatalogs();
		assertEquals(supportsCatalogs, this.connectionProfile.getDatabase().supportsCatalogs());
		if (supportsCatalogs) {
			assertTrue(this.connectionProfile.getDatabase().getCatalogsSize() > 0);
			assertEquals(0, this.connectionProfile.getDatabase().getSchemataSize());
		} else {
			assertEquals(0, this.connectionProfile.getDatabase().getCatalogsSize());
			assertTrue(this.connectionProfile.getDatabase().getSchemataSize() > 0);
		}

		this.connectionProfile.removeConnectionListener(listener);
		this.connectionProfile.disconnect();
	}

	protected abstract boolean supportsCatalogs();

//	public void testDEBUG() throws Exception {
//		this.connectionProfile.connect();
//		this.dumpJDBCCatalogs();
//		this.dumpJDBCSchemata();
//		this.dumpDatabaseContainers();
//		this.connectionProfile.disconnect();
//	}


	// ********** convenience methods **********

	protected ConnectionProfileFactory getConnectionProfileFactory() {
		return JptJpaDbPlugin.getConnectionProfileFactory();
	}

	protected ConnectionProfile getConnectionProfile() {
		return this.connectionProfile;
	}

	protected Database getDatabase() {
		return this.connectionProfile.getDatabase();
	}

	protected Catalog getDefaultCatalog() {
		return this.getDatabase().getDefaultCatalog();
	}

	/**
	 * only valid on databases that do not support catalogs
	 */
	protected Schema getDefaultSchema() {
		return this.getDatabase().getDefaultSchema();
	}

	protected Catalog getCatalogNamed(String catalogName) {
		return this.connectionProfile.getDatabase().getCatalogNamed(catalogName);
	}

	protected String getRequiredPlatformProperty(String propertyKey) {
		String propertyValue = this.platformProperties.getProperty(propertyKey);
		if (StringTools.stringIsEmpty(propertyValue)) {
			throw new IllegalArgumentException("The database platform properties file '" + this.getPlatformPropertiesFilePath()
					+ "' is missing a value for the property '" + propertyKey + "'.");
		}
		return propertyValue;
	}

	protected boolean connectionProfileHasAnyListeners() {
		return connectionProfileHasAnyListeners(this.connectionProfile);
	}

	protected static boolean connectionProfileHasAnyListeners(ConnectionProfile cp) {
		return ((Boolean) ReflectionTools.executeMethod(cp, "hasAnyListeners")).booleanValue();
	}

	protected boolean connectionProfileHasNoListeners() {
		return connectionProfileHasNoListeners(this.connectionProfile);
	}

	protected static boolean connectionProfileHasNoListeners(ConnectionProfile cp) {
		return ((Boolean) ReflectionTools.executeMethod(cp, "hasNoListeners")).booleanValue();
	}


	// ********** DTP model **********

	protected ProfileManager getDTPProfileManager() {
		return ProfileManager.getInstance();
	}

	protected IConnectionProfile getDTPConnectionProfile() {
		return getDTPConnectionProfile(this.connectionProfile);
	}

	protected static IConnectionProfile getDTPConnectionProfile(ConnectionProfile cp) {
		return (IConnectionProfile) ReflectionTools.getFieldValue(cp, "dtpConnectionProfile");
	}

	protected org.eclipse.datatools.modelbase.sql.schema.Database getDTPDatabase() {
		return getDTPDatabase(this.connectionProfile.getDatabase());
	}

	protected static org.eclipse.datatools.modelbase.sql.schema.Database getDTPDatabase(Database database) {
		return (org.eclipse.datatools.modelbase.sql.schema.Database) ReflectionTools.getFieldValue(database, "dtpDatabase");
	}

	@SuppressWarnings("unchecked")
	protected List<org.eclipse.datatools.modelbase.sql.schema.Catalog> getDTPCatalogs() {
		return this.getDTPDatabase().getCatalogs();
	}

	protected org.eclipse.datatools.modelbase.sql.schema.Catalog getFirstDTPCatalog() {
		return this.getDTPCatalogs().get(0);
	}

	protected org.eclipse.datatools.modelbase.sql.schema.Catalog getDTPCatalogNamed(String name) {
		return getDTPCatalog(this.getDatabase().getCatalogNamed(name));
	}

	protected static org.eclipse.datatools.modelbase.sql.schema.Catalog getDTPCatalog(Catalog catalog) {
		return (org.eclipse.datatools.modelbase.sql.schema.Catalog) ReflectionTools.getFieldValue(catalog, "dtpCatalog");
	}

	protected org.eclipse.datatools.modelbase.sql.schema.Schema getDTPSchemaNamed(String name) {
		return getDTPSchema(this.getDatabase().getSchemaNamed(name));
	}

	protected static org.eclipse.datatools.modelbase.sql.schema.Schema getDTPSchema(Schema schema) {
		return (org.eclipse.datatools.modelbase.sql.schema.Schema) ReflectionTools.getFieldValue(schema, "dtpSchema");
	}


	// ********** execute SQL **********

	/**
	 * ignore any errors (useful for dropping database objects that might
	 * not be there)
	 */
	protected void executeUpdateIgnoreErrors(String sql) {
		try {
			this.executeUpdate(sql);
		} catch (Exception ex) {
//			System.err.println("SQL: " + sql);
//			ex.printStackTrace();
		}
	}

	protected void executeUpdate(String sql) throws SQLException {
		Statement jdbcStatement = this.createJDBCStatement();
		try {
			jdbcStatement.executeUpdate(sql);
		} finally {
			jdbcStatement.close();
		}
	}

	protected void dump(String sql) throws SQLException {
		this.dump(sql, 30);
	}

	protected void dump(String sql, int columnWidth) throws SQLException {
		IndentingPrintWriter pw = new IndentingPrintWriter(new OutputStreamWriter(System.out));
		// synchronize the console so everything is contiguous
		synchronized (System.out) {
			this.dumpOn(sql, pw, columnWidth);
		}
		pw.flush();
	}

	protected void dumpOn(String sql, IndentingPrintWriter pw, int columnWidth) throws SQLException {
		pw.println(sql);
		for (HashMap<String, Object> row : this.execute(sql)) {
			for (Map.Entry<String, Object> field : row.entrySet()) {
				StringTools.padOrTruncateOn(String.valueOf(field.getKey()), columnWidth/2, pw);
				pw.print('=');
				StringTools.padOrTruncateOn(String.valueOf(field.getValue()), columnWidth/2, pw);
				pw.print(' ');
			}
			pw.println();
		}
	}

	protected ArrayList<HashMap<String, Object>> execute(String sql) throws SQLException {
		Statement jdbcStatement = this.createJDBCStatement();
		jdbcStatement.execute(sql);
		ArrayList<HashMap<String, Object>> rows = this.buildRows(jdbcStatement.getResultSet());
		jdbcStatement.close();
		return rows;
	}

	protected ArrayList<HashMap<String, Object>> buildRows(ResultSet resultSet) throws SQLException {
		ArrayList<HashMap<String, Object>> rows = new ArrayList<HashMap<String, Object>>();
		CollectionTools.addAll(rows, this.buildResultSetIterator(resultSet));
		return rows;
	}

	protected Iterator<HashMap<String, Object>> buildResultSetIterator(ResultSet resultSet) throws SQLException {
		return new ResultSetIterator<HashMap<String, Object>>(resultSet, new MapResultSetIteratorAdapter(resultSet.getMetaData()));
	}

	public static class MapResultSetIteratorAdapter
		implements ResultSetIterator.Adapter<HashMap<String, Object>>
	{
		private final int columnCount;
		private final String[] columnNames;
		public MapResultSetIteratorAdapter(ResultSetMetaData rsMetaData) throws SQLException {
			super();
			this.columnCount = rsMetaData.getColumnCount();
			this.columnNames = new String[this.columnCount + 1];  // leave zero slot empty
			for (int i = 1; i <= this.columnCount; i++) {  // NB: ResultSet index/subscript is 1-based
				this.columnNames[i] = rsMetaData.getColumnName(i);
			}
		}
		public HashMap<String, Object> buildNext(ResultSet rs) throws SQLException {
			HashMap<String, Object> row = new HashMap<String, Object>(this.columnCount);
			for (int i = 1; i <= this.columnCount; i++) {  // NB: ResultSet index/subscript is 1-based
				row.put(this.columnNames[i], rs.getObject(i));
			}
			return row;
		}
	}

	protected Statement createJDBCStatement() throws SQLException {
		return this.getJDBCConnection().createStatement();
	}

	protected Connection getJDBCConnection() {
		return this.connectionProfile.getJDBCConnection();
	}

	protected DatabaseMetaData getDatabaseMetaData() throws SQLException {
		return this.getJDBCConnection().getMetaData();
	}


	// ********** dump DTP metadata **********

	/**
	 * dump all the database metadata to the console
	 */
	protected void dumpDatabase() {
		this.dumpDatabase(true);
	}

	/**
	 * dump the database catalogs and schemata to the console
	 */
	protected void dumpDatabaseContainers() {
		this.dumpDatabase(false);
	}

	protected void dumpDatabase(boolean deep) {
		IndentingPrintWriter pw = new IndentingPrintWriter(new OutputStreamWriter(System.out));
		// synchronize the console so everything is contiguous
		synchronized (System.out) {
			this.dumpDatabaseOn(pw, deep);
		}
		pw.flush();
	}

	protected void dumpDatabaseOn(IndentingPrintWriter pw, boolean deep) {
		Database database = this.connectionProfile.getDatabase();
		pw.print("database: ");
		pw.println(database.getName());
		if (database.supportsCatalogs()) {
			for (Catalog catalog : database.getCatalogs()) {
				this.dumpCatalogOn(catalog, pw, deep);
			}
		} else {
			this.dumpSchemaContainerOn(database, pw, deep);
		}
	}

	protected void dumpCatalogOn(Catalog catalog, IndentingPrintWriter pw, boolean deep) {
		pw.print("catalog: ");
		pw.println(catalog.getName());
		pw.indent();
			this.dumpSchemaContainerOn(catalog, pw, deep);
		pw.undent();
	}

	protected void dumpSchemaContainerOn(SchemaContainer schemaContainer, IndentingPrintWriter pw, boolean deep) {
		for (Schema schema : schemaContainer.getSchemata()) {
			this.dumpSchemaOn(schema, pw, deep);
		}
	}

	protected void dumpSchema(Schema schema) {
		this.dumpSchema(schema, true);
	}

	protected void dumpSchema(Schema schema, boolean deep) {
		IndentingPrintWriter pw = new IndentingPrintWriter(new OutputStreamWriter(System.out));
		// synchronize the console so everything is contiguous
		synchronized (System.out) {
			this.dumpSchemaOn(schema, pw, deep);
		}
		pw.flush();
	}

	protected void dumpSchemaOn(Schema schema, IndentingPrintWriter pw, boolean deep) {
		pw.print("schema: ");
		pw.println(schema.getName());
		if (deep) {
			pw.indent();
				for (Table table : schema.getTables()) {
					this.dumpTableOn(table, pw);
				}
				for (Sequence sequence : schema.getSequences()) {
					this.dumpSequenceOn(sequence, pw);
				}
			pw.undent();
		}
	}

	protected void dumpTableOn(Table table, IndentingPrintWriter pw) {
		pw.print("table: ");
		pw.println(table.getName());
		pw.indent();
			for (Column column : table.getColumns()) {
				this.dumpColumnOn(column, pw);
			}
			for (ForeignKey foreignKey : table.getForeignKeys()) {
				this.dumpForeignKeyOn(foreignKey, pw);
			}
		pw.undent();
	}

	protected void dumpColumnOn(Column column, IndentingPrintWriter pw) {
		pw.print("column: ");
		pw.print(column.getName());
		pw.print(" : ");
		pw.print(column.getDataTypeName());
		if (column.isPartOfPrimaryKey()) {
			pw.print(" [primary key]");
		}
		pw.println();
	}

	protected void dumpForeignKeyOn(ForeignKey foreignKey, IndentingPrintWriter pw) {
		pw.print("foreign key: ");
		pw.print(foreignKey.getName());
		pw.print("=>");
		pw.print(foreignKey.getReferencedTable().getName());
		pw.print(" (");
		for (Iterator<ForeignKey.ColumnPair> stream = foreignKey.getColumnPairs().iterator(); stream.hasNext(); ) {
			ForeignKey.ColumnPair cp = stream.next();
			pw.print(cp.getBaseColumn().getName());
			pw.print("=>");
			pw.print(cp.getReferencedColumn().getName());
			if (stream.hasNext()) {
				pw.print(", ");
			}
		}
		pw.print(')');
		pw.println();
	}

	protected void dumpSequenceOn(Sequence sequence, IndentingPrintWriter pw) {
		pw.print("sequence: ");
		pw.println(sequence.getName());
	}


	// ********** dump JDBC metadata **********

	protected void dumpJDBCCatalogs() throws SQLException {
		IndentingPrintWriter pw = new IndentingPrintWriter(new OutputStreamWriter(System.out));
		// synchronize the console so everything is contiguous
		synchronized (System.out) {
			this.dumpJDBCCatalogsOn(pw);
		}
		pw.flush();
	}

	protected void dumpJDBCCatalogsOn(IndentingPrintWriter pw) throws SQLException {
		pw.println("JDBC catalogs: ");
		pw.indent();
			ArrayList<HashMap<String, Object>> rows = this.buildRows(this.getDatabaseMetaData().getCatalogs());
			for (Iterator<HashMap<String, Object>> stream = rows.iterator(); stream.hasNext(); ) {
				HashMap<String, Object> row = stream.next();
				pw.println(row.get("TABLE_CAT"));
			}
		pw.undent();
	}

	protected void dumpJDBCSchemata() throws SQLException {
		IndentingPrintWriter pw = new IndentingPrintWriter(new OutputStreamWriter(System.out));
		// synchronize the console so everything is contiguous
		synchronized (System.out) {
			this.dumpJDBCSchemataOn(pw);
		}
		pw.flush();
	}

	protected void dumpJDBCSchemataOn(IndentingPrintWriter pw) throws SQLException {
		pw.println("JDBC schemata: ");
		pw.indent();
			ArrayList<HashMap<String, Object>> rows = this.buildRows(this.getDatabaseMetaData().getSchemas());
			for (HashMap<String, Object> row : rows) {
				if (row.size() == 2) {  // catalogs were added in jdk 1.4
					Object catalog = row.get("TABLE_CATALOG");
					pw.print(catalog);
					pw.print('.');
				}
				Object schema = row.get("TABLE_SCHEM");
				pw.println(schema);
			}
		pw.undent();
	}


	// ********** connection profile listener **********

	protected static class TestConnectionProfileListener implements ConnectionProfileListener {
		public String addedName;
		public String removedName;
		public String renamedOldName;
		public String renamedNewName;

		public void connectionProfileAdded(String name) {
			this.addedName = name;
		}
		public void connectionProfileRemoved(String name) {
			this.removedName = name;
		}
		public void connectionProfileRenamed(String oldName, String newName) {
			this.renamedOldName = oldName;
			this.renamedNewName = newName;
		}
		public void clear() {
			this.addedName = null;
			this.removedName = null;
			this.renamedOldName = null;
			this.renamedNewName = null;
		}
	}


	// ********** connection listener **********

	protected static class TestConnectionListener implements ConnectionListener {
		public ConnectionProfile openedProfile;
		public ConnectionProfile modifiedProfile;
		public ConnectionProfile okToCloseProfile;
		public ConnectionProfile aboutToCloseProfile;
		public ConnectionProfile closedProfile;
		public Database changedDatabase;
		public Catalog changedCatalog;
		public Schema changedSchema;
		public Sequence changedSequence;
		public Table changedTable;
		public Column changedColumn;
		public ForeignKey changedForeignKey;

		public void opened(ConnectionProfile profile) {
			this.openedProfile = profile;
		}
		public void modified(ConnectionProfile profile) {
			this.modifiedProfile = profile;
		}
		public boolean okToClose(ConnectionProfile profile) {
			this.okToCloseProfile = profile;
			return true;
		}
		public void aboutToClose(ConnectionProfile profile) {
			this.aboutToCloseProfile = profile;
		}
		public void closed(ConnectionProfile profile) {
			this.closedProfile = profile;
		}
		public void databaseChanged(ConnectionProfile profile, Database database) {
			this.changedDatabase = database;
		}
		public void catalogChanged(ConnectionProfile profile, Catalog catalog) {
			this.changedCatalog = catalog;
		}
		public void schemaChanged(ConnectionProfile profile, Schema schema) {
			this.changedSchema = schema;
		}
		public void sequenceChanged(ConnectionProfile profile, Sequence sequence) {
			this.changedSequence = sequence;
		}
		public void tableChanged(ConnectionProfile profile, Table table) {
			this.changedTable = table;
		}
		public void columnChanged(ConnectionProfile profile, Column column) {
			this.changedColumn = column;
		}
		public void foreignKeyChanged(ConnectionProfile profile, ForeignKey foreignKey) {
			this.changedForeignKey = foreignKey;
		}
		public void clear() {
			this.openedProfile = null;
			this.modifiedProfile = null;
			this.okToCloseProfile = null;
			this.aboutToCloseProfile = null;
			this.closedProfile = null;
			this.changedDatabase = null;
			this.changedCatalog = null;
			this.changedSchema = null;
			this.changedSequence = null;
			this.changedTable = null;
			this.changedColumn = null;
			this.changedForeignKey = null;
		}
	}

}
