Java tutorial
package org.apache.ddlutils; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.FileInputStream; import java.io.InputStream; import java.io.StringReader; import java.util.Iterator; import java.util.Map; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.DynaBean; import org.apache.commons.beanutils.DynaProperty; import org.apache.commons.dbcp.BasicDataSource; import org.apache.ddlutils.io.DataReader; import org.apache.ddlutils.io.DataToDatabaseSink; import org.apache.ddlutils.model.Database; import org.apache.ddlutils.platform.CreationParameters; /** * Base class for database writer tests. * * @version $Revision: 289996 $ */ public abstract class TestDatabaseWriterBase extends TestPlatformBase { /** The name of the property that specifies properties file with the settings for the connection to test against. */ public static final String JDBC_PROPERTIES_PROPERTY = "jdbc.properties.file"; /** The prefix for properties of the datasource. */ public static final String DATASOURCE_PROPERTY_PREFIX = "datasource."; /** The prefix for properties for ddlutils. */ public static final String DDLUTILS_PROPERTY_PREFIX = "ddlutils."; /** The property for specifying the platform. */ public static final String DDLUTILS_PLATFORM_PROPERTY = DDLUTILS_PROPERTY_PREFIX + "platform"; /** The property specifying the catalog for the tests. */ public static final String DDLUTILS_CATALOG_PROPERTY = DDLUTILS_PROPERTY_PREFIX + "catalog"; /** The property specifying the schema for the tests. */ public static final String DDLUTILS_SCHEMA_PROPERTY = DDLUTILS_PROPERTY_PREFIX + "schema"; /** The prefix for table creation properties. */ public static final String DDLUTILS_TABLE_CREATION_PREFIX = DDLUTILS_PROPERTY_PREFIX + "tableCreation."; /** The test properties as defined by an external properties file. */ private static Properties _testProps; /** The data source to test against. */ private static DataSource _dataSource; /** The database name. */ private static String _databaseName; /** The database model. */ private Database _model; /** * Creates a new test case instance. */ public TestDatabaseWriterBase() { super(); init(); } /** * Returns the test properties. * * @return The properties */ protected Properties getTestProperties() { if (_testProps == null) { String propFile = System.getProperty(JDBC_PROPERTIES_PROPERTY); if (propFile == null) { throw new RuntimeException( "Please specify the properties file via the jdbc.properties.file environment variable"); } try { InputStream propStream = getClass().getResourceAsStream(propFile); if (propStream == null) { propStream = new FileInputStream(propFile); } Properties props = new Properties(); props.load(propStream); _testProps = props; } catch (Exception ex) { throw new RuntimeException(ex); } } return _testProps; } /** * Initializes the test datasource and the platform. */ private void init() { // the data source won't change during the tests, hence // it is static and needs to be initialized only once if (_dataSource != null) { return; } Properties props = getTestProperties(); try { String dataSourceClass = props.getProperty(DATASOURCE_PROPERTY_PREFIX + "class", BasicDataSource.class.getName()); _dataSource = (DataSource) Class.forName(dataSourceClass).newInstance(); for (Iterator it = props.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String propName = (String) entry.getKey(); if (propName.startsWith(DATASOURCE_PROPERTY_PREFIX) && !propName.equals(DATASOURCE_PROPERTY_PREFIX + "class")) { BeanUtils.setProperty(_dataSource, propName.substring(DATASOURCE_PROPERTY_PREFIX.length()), entry.getValue()); } } } catch (Exception ex) { throw new DatabaseOperationException(ex); } _databaseName = props.getProperty(DDLUTILS_PLATFORM_PROPERTY); if (_databaseName == null) { // property not set, then try to determine _databaseName = new PlatformUtils().determineDatabaseType(_dataSource); if (_databaseName == null) { throw new DatabaseOperationException( "Could not determine platform from datasource, please specify it in the jdbc.properties via the ddlutils.platform property"); } } } /** * Returns the test table creation parameters for the given model. * * @param model The model * @return The creation parameters */ protected CreationParameters getTableCreationParameters(Database model) { CreationParameters params = new CreationParameters(); for (Iterator entryIt = _testProps.entrySet().iterator(); entryIt.hasNext();) { Map.Entry entry = (Map.Entry) entryIt.next(); String name = (String) entry.getKey(); String value = (String) entry.getValue(); if (name.startsWith(DDLUTILS_TABLE_CREATION_PREFIX)) { name = name.substring(DDLUTILS_TABLE_CREATION_PREFIX.length()); for (int tableIdx = 0; tableIdx < model.getTableCount(); tableIdx++) { params.addParameter(model.getTable(tableIdx), name, value); } } } return params; } /** * Returns the data source. * * @return The data source */ protected DataSource getDataSource() { return _dataSource; } /** * {@inheritDoc} */ protected String getDatabaseName() { return _databaseName; } /** * Returns the database model. * * @return The model */ protected Database getModel() { return _model; } /** * {@inheritDoc} */ protected void setUp() throws Exception { super.setUp(); getPlatform().setDataSource(getDataSource()); } /** * {@inheritDoc} */ protected void tearDown() throws Exception { if (_model != null) { dropDatabase(); _model = null; } super.tearDown(); } /** * Creates a new database from the given XML database schema. * * @param schemaXml The XML database schema * @return The parsed database model */ protected Database createDatabase(String schemaXml) throws DatabaseOperationException { Database model = parseDatabaseFromString(schemaXml); createDatabase(model); return model; } /** * Creates a new database from the given model. * * @param model The model */ protected void createDatabase(Database model) throws DatabaseOperationException { try { _model = model; getPlatform().setSqlCommentsOn(false); getPlatform().createTables(_model, getTableCreationParameters(_model), false, false); } catch (Exception ex) { throw new DatabaseOperationException(ex); } } /** * Alters the database to match the given model. * * @param schemaXml The model XML * @return The model object */ protected Database alterDatabase(String schemaXml) throws DatabaseOperationException { Database model = parseDatabaseFromString(schemaXml); alterDatabase(model); return model; } /** * Alters the database to match the given model. * * @param model The model */ protected void alterDatabase(Database model) throws DatabaseOperationException { Properties props = getTestProperties(); String catalog = props.getProperty(DDLUTILS_CATALOG_PROPERTY); String schema = props.getProperty(DDLUTILS_SCHEMA_PROPERTY); try { _model = model; _model.resetDynaClassCache(); getPlatform().setSqlCommentsOn(false); getPlatform().alterTables(catalog, schema, null, _model, getTableCreationParameters(_model), false); } catch (Exception ex) { throw new DatabaseOperationException(ex); } } /** * Inserts data into the database. * * @param dataXml The data xml * @return The database */ protected Database insertData(String dataXml) throws DatabaseOperationException { try { DataReader dataReader = new DataReader(); dataReader.setModel(_model); dataReader.setSink(new DataToDatabaseSink(getPlatform(), _model)); dataReader.getSink().start(); dataReader.parse(new StringReader(dataXml)); dataReader.getSink().end(); return _model; } catch (Exception ex) { throw new DatabaseOperationException(ex); } } /** * Drops the tables defined in the database model. */ protected void dropDatabase() throws DatabaseOperationException { getPlatform().dropTables(_model, true); } /** * Reads the database model from a live database. * * @param databaseName The name of the resulting database * @return The model */ protected Database readModelFromDatabase(String databaseName) { Properties props = getTestProperties(); String catalog = props.getProperty(DDLUTILS_CATALOG_PROPERTY); String schema = props.getProperty(DDLUTILS_SCHEMA_PROPERTY); return getPlatform().readModelFromDatabase(databaseName, catalog, schema, null); } /** * Returns the SQL for altering the live database so that it matches the given model. * * @param desiredModel The desired model * @return The alteration SQL */ protected String getAlterTablesSql(Database desiredModel) { Properties props = getTestProperties(); String catalog = props.getProperty(DDLUTILS_CATALOG_PROPERTY); String schema = props.getProperty(DDLUTILS_SCHEMA_PROPERTY); return getPlatform().getAlterTablesSql(catalog, schema, null, desiredModel); } /** * Determines the value of the bean's property that has the given name. Depending on the * case-setting of the current builder, the case of teh name is considered or not. * * @param bean The bean * @param propName The name of the property * @return The value */ protected Object getPropertyValue(DynaBean bean, String propName) { if (getPlatform().isDelimitedIdentifierModeOn()) { return bean.get(propName); } else { DynaProperty[] props = bean.getDynaClass().getDynaProperties(); for (int idx = 0; idx < props.length; idx++) { if (propName.equalsIgnoreCase(props[idx].getName())) { return bean.get(props[idx].getName()); } } throw new IllegalArgumentException("The bean has no property with the name " + propName); } } }