CAY-2009 Non-blocking connection pool

* making DriverDataSource immutable (with deprecation of setters)


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/12e83f21
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/12e83f21
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/12e83f21

Branch: refs/heads/master
Commit: 12e83f21b1cb2d6e3c629e4fc0028552372137c1
Parents: 00dc721
Author: aadamchik <[email protected]>
Authored: Mon May 18 15:42:21 2015 +0300
Committer: aadamchik <[email protected]>
Committed: Mon May 18 16:42:43 2015 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/access/DbGenerator.java  | 1033 +++++++++---------
 .../cayenne/datasource/DataSourceBuilder.java   |    4 +-
 .../cayenne/datasource/DriverDataSource.java    |   75 +-
 .../datasource/BasePoolingDataSourceIT.java     |    3 +-
 ...lingDataSource_FailingValidationQueryIT.java |    5 +-
 .../apache/cayenne/tools/DbGeneratorTask.java   |  213 ++--
 .../configuration/DriverDataSourceFactory.java  |   29 +-
 .../dialog/pref/DataSourcePreferences.java      |  534 +++++----
 .../cayenne/modeler/pref/DBConnectionInfo.java  |  572 +++++-----
 .../apache/cayenne/tools/DbGeneratorMojo.java   |    2 +-
 10 files changed, 1234 insertions(+), 1236 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/12e83f21/cayenne-server/src/main/java/org/apache/cayenne/access/DbGenerator.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DbGenerator.java 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DbGenerator.java
index 275e07e..fa340e0 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DbGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DbGenerator.java
@@ -54,530 +54,517 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 /**
- * Utility class that generates database schema based on Cayenne mapping. It 
is a logical
- * counterpart of DbLoader class.
+ * Utility class that generates database schema based on Cayenne mapping. It is
+ * a logical counterpart of DbLoader class.
  */
 public class DbGenerator {
 
-    private Log logObj = LogFactory.getLog(DbGenerator.class);
-
-    protected DbAdapter adapter;
-    protected DataMap map;
-
-    // optional DataDomain needed for correct FK generation in cross-db 
situations
-    protected DataDomain domain;
-
-    protected JdbcEventLogger jdbcEventLogger;
-
-    // stores generated SQL statements
-    protected Map<String, Collection<String>> dropTables;
-    protected Map<String, String> createTables;
-    protected Map<String, List<String>> createConstraints;
-    protected List<String> createPK;
-    protected List<String> dropPK;
-
-    /**
-     * Contains all DbEntities ordered considering their interdependencies.
-     * DerivedDbEntities are filtered out of this list.
-     */
-    protected List<DbEntity> dbEntitiesInInsertOrder;
-    protected List<DbEntity> dbEntitiesRequiringAutoPK;
-
-    protected boolean shouldDropTables;
-    protected boolean shouldCreateTables;
-    protected boolean shouldDropPKSupport;
-    protected boolean shouldCreatePKSupport;
-    protected boolean shouldCreateFKConstraints;
-
-    protected ValidationResult failures;
-
-    /**
-     * @since 3.1
-     */
-    public DbGenerator(DbAdapter adapter, DataMap map, JdbcEventLogger logger) 
{
-        this(adapter, map, logger, Collections.<DbEntity> emptyList());
-    }
-
-    /**
-     * @since 3.1
-     */
-    public DbGenerator(DbAdapter adapter, DataMap map, JdbcEventLogger logger,
-            Collection<DbEntity> excludedEntities) {
-        this(adapter, map, excludedEntities, null, logger);
-    }
-
-    /**
-     * Creates and initializes new DbGenerator instance.
-     * 
-     * @param adapter DbAdapter corresponding to the database
-     * @param map DataMap whose entities will be used in schema generation
-     * @param excludedEntities entities that should be ignored during schema 
generation
-     * @param domain optional DataDomain used to detect cross-database 
relationships.
-     * @since 3.1
-     */
-    public DbGenerator(DbAdapter adapter, DataMap map,
-            Collection<DbEntity> excludedEntities, DataDomain domain,
-            JdbcEventLogger logger) {
-        // sanity check
-        if (adapter == null) {
-            throw new IllegalArgumentException("Adapter must not be null.");
-        }
-
-        if (map == null) {
-            throw new IllegalArgumentException("DataMap must not be null.");
-        }
-
-        this.domain = domain;
-        this.map = map;
-        this.adapter = adapter;
-        this.jdbcEventLogger = logger;
-
-        prepareDbEntities(excludedEntities);
-        resetToDefaults();
-        buildStatements();
-    }
-
-    protected void resetToDefaults() {
-        this.shouldDropTables = false;
-        this.shouldDropPKSupport = false;
-        this.shouldCreatePKSupport = true;
-        this.shouldCreateTables = true;
-        this.shouldCreateFKConstraints = true;
-    }
-
-    /**
-     * Creates and stores internally a set of statements for database schema 
creation,
-     * ignoring configured schema creation preferences. Statements are NOT 
executed in
-     * this method.
-     */
-    protected void buildStatements() {
-        dropTables = new HashMap<String, Collection<String>>();
-        createTables = new HashMap<String, String>();
-        createConstraints = new HashMap<String, List<String>>();
-
-        DbAdapter adapter = getAdapter();
-        for (final DbEntity dbe : this.dbEntitiesInInsertOrder) {
-
-            String name = dbe.getName();
-
-            // build "DROP TABLE"
-            dropTables.put(name, adapter.dropTableStatements(dbe));
-
-            // build "CREATE TABLE"
-            createTables.put(name, adapter.createTable(dbe));
-
-            // build constraints
-            createConstraints.put(name, createConstraintsQueries(dbe));
-        }
-
-        PkGenerator pkGenerator = adapter.getPkGenerator();
-        dropPK = pkGenerator.dropAutoPkStatements(dbEntitiesRequiringAutoPK);
-        createPK = 
pkGenerator.createAutoPkStatements(dbEntitiesRequiringAutoPK);
-    }
-
-    /**
-     * Returns <code>true</code> if there is nothing to be done by this 
generator. If
-     * <code>respectConfiguredSettings</code> is <code>true</code>, checks are 
done
-     * applying currently configured settings, otherwise check is done, 
assuming that all
-     * possible generated objects.
-     */
-    public boolean isEmpty(boolean respectConfiguredSettings) {
-        if (dbEntitiesInInsertOrder.isEmpty() && 
dbEntitiesRequiringAutoPK.isEmpty()) {
-            return true;
-        }
-
-        if (!respectConfiguredSettings) {
-            return false;
-        }
-
-        return !(shouldDropTables
-                || shouldCreateTables
-                || shouldCreateFKConstraints
-                || shouldCreatePKSupport || shouldDropPKSupport);
-    }
-
-    /** Returns DbAdapter associated with this DbGenerator. */
-    public DbAdapter getAdapter() {
-        return adapter;
-    }
-
-    /**
-     * Returns a list of all schema statements that should be executed with 
the current
-     * configuration.
-     */
-    public List<String> configuredStatements() {
-        List<String> list = new ArrayList<String>();
-
-        if (shouldDropTables) {
-            ListIterator<DbEntity> it = dbEntitiesInInsertOrder
-                    .listIterator(dbEntitiesInInsertOrder.size());
-            while (it.hasPrevious()) {
-                DbEntity ent = it.previous();
-                list.addAll(dropTables.get(ent.getName()));
-            }
-        }
-
-        if (shouldCreateTables) {
-            for (final DbEntity ent : dbEntitiesInInsertOrder) {
-                list.add(createTables.get(ent.getName()));
-            }
-        }
-
-        if (shouldCreateFKConstraints) {
-            for (final DbEntity ent : dbEntitiesInInsertOrder) {
-                List<String> fks = createConstraints.get(ent.getName());
-                list.addAll(fks);
-            }
-        }
-
-        if (shouldDropPKSupport) {
-            list.addAll(dropPK);
-        }
-
-        if (shouldCreatePKSupport) {
-            list.addAll(createPK);
-        }
-
-        return list;
-    }
-
-    /**
-     * Creates a temporary DataSource out of DataSourceInfo and invokes
-     * <code>public void runGenerator(DataSource ds)</code>.
-     */
-    public void runGenerator(DataSourceInfo dsi) throws Exception {
-        this.failures = null;
-
-        // do a pre-check. Maybe there is no need to run anything
-        // and therefore no need to create a connection
-        if (isEmpty(true)) {
-            return;
-        }
-
-        Driver driver = (Driver) 
Class.forName(dsi.getJdbcDriver()).newInstance();
-        DataSource dataSource = new DriverDataSource(
-                driver,
-                dsi.getDataSourceUrl(),
-                dsi.getUserName(),
-                dsi.getPassword());
-
-        runGenerator(dataSource);
-    }
-
-    /**
-     * Executes a set of commands to drop/create database objects. This is the 
main worker
-     * method of DbGenerator. Command set is built based on pre-configured 
generator
-     * settings.
-     */
-    public void runGenerator(DataSource ds) throws Exception {
-        this.failures = null;
-
-        Connection connection = ds.getConnection();
-
-        try {
-
-            // drop tables
-            if (shouldDropTables) {
-                ListIterator<DbEntity> it = dbEntitiesInInsertOrder
-                        .listIterator(dbEntitiesInInsertOrder.size());
-                while (it.hasPrevious()) {
-                    DbEntity ent = it.previous();
-                    for (String statement : dropTables.get(ent.getName())) {
-                        safeExecute(connection, statement);
-                    }
-                }
-            }
-
-            // create tables
-            List<String> createdTables = new ArrayList<String>();
-            if (shouldCreateTables) {
-                for (final DbEntity ent : dbEntitiesInInsertOrder) {
-
-                    // only create missing tables
-
-                    safeExecute(connection, createTables.get(ent.getName()));
-                    createdTables.add(ent.getName());
-                }
-            }
-
-            // create FK
-            if (shouldCreateTables && shouldCreateFKConstraints) {
-                for (DbEntity ent : dbEntitiesInInsertOrder) {
-
-                    if (createdTables.contains(ent.getName())) {
-                        List<String> fks = 
createConstraints.get(ent.getName());
-                        for (String fk : fks) {
-                            safeExecute(connection, fk);
-                        }
-                    }
-                }
-            }
-
-            // drop PK
-            if (shouldDropPKSupport) {
-                List<String> dropAutoPKSQL = getAdapter()
-                        .getPkGenerator()
-                        .dropAutoPkStatements(dbEntitiesRequiringAutoPK);
-                for (final String sql : dropAutoPKSQL) {
-                    safeExecute(connection, sql);
-                }
-            }
-
-            // create pk
-            if (shouldCreatePKSupport) {
-                List<String> createAutoPKSQL = getAdapter()
-                        .getPkGenerator()
-                        .createAutoPkStatements(dbEntitiesRequiringAutoPK);
-                for (final String sql : createAutoPKSQL) {
-                    safeExecute(connection, sql);
-                }
-            }
-
-            new DbGeneratorPostprocessor().execute(connection, getAdapter());
-        }
-        finally {
-            connection.close();
-        }
-    }
-
-    /**
-     * Builds and executes a SQL statement, catching and storing SQL 
exceptions resulting
-     * from invalid SQL. Only non-recoverable exceptions are rethrown.
-     * 
-     * @since 1.1
-     */
-    protected boolean safeExecute(Connection connection, String sql) throws 
SQLException {
-        Statement statement = connection.createStatement();
-
-        try {
-            jdbcEventLogger.logQuery(sql, null);
-            statement.execute(sql);
-            return true;
-        }
-        catch (SQLException ex) {
-            if (this.failures == null) {
-                this.failures = new ValidationResult();
-            }
-
-            failures.addFailure(new SimpleValidationFailure(sql, 
ex.getMessage()));
-            jdbcEventLogger.logQueryError(ex);
-            return false;
-        }
-        finally {
-            statement.close();
-        }
-    }
-
-    /**
-     * Creates FK and UNIQUE constraint statements for a given table.
-     * 
-     * @since 3.0
-     */
-    public List<String> createConstraintsQueries(DbEntity table) {
-        List<String> list = new ArrayList<String>();
-        for (final DbRelationship rel : table.getRelationships()) {
-
-            if (rel.isToMany()) {
-                continue;
-            }
-
-            // skip FK to a different DB
-            if (domain != null) {
-                DataMap srcMap = rel.getSourceEntity().getDataMap();
-                DataMap targetMap = rel.getTargetEntity().getDataMap();
-
-                if (srcMap != null && targetMap != null && srcMap != 
targetMap) {
-                    if (domain.lookupDataNode(srcMap) != 
domain.lookupDataNode(targetMap)) {
-                        continue;
-                    }
-                }
-            }
-
-            // create an FK CONSTRAINT only if the relationship is to PK
-            // and if this is not a dependent PK
-
-            // create UNIQUE CONSTRAINT on FK if reverse relationship is to-one
-
-            if (rel.isToPK() && !rel.isToDependentPK()) {
-
-                if (getAdapter().supportsUniqueConstraints()) {
-
-                    DbRelationship reverse = rel.getReverseRelationship();
-                    if (reverse != null && !reverse.isToMany() && 
!reverse.isToPK()) {
-
-                        String unique = getAdapter().createUniqueConstraint(
-                                (DbEntity) rel.getSourceEntity(),
-                                rel.getSourceAttributes());
-                        if (unique != null) {
-                            list.add(unique);
-                        }
-                    }
-                }
-
-                String fk = getAdapter().createFkConstraint(rel);
-                if (fk != null) {
-                    list.add(fk);
-                }
-            }
-        }
-        return list;
-    }
-
-    /**
-     * Returns an object representing a collection of failures that occurred 
on the last
-     * "runGenerator" invocation, or null if there were no failures. Failures 
usually
-     * indicate problems with generated DDL (such as "create...", "drop...", 
etc.) and
-     * usually happen due to the DataMap being out of sync with the database.
-     * 
-     * @since 1.1
-     */
-    public ValidationResult getFailures() {
-        return failures;
-    }
-
-    /**
-     * Returns whether DbGenerator is configured to create primary key support 
for DataMap
-     * entities.
-     */
-    public boolean shouldCreatePKSupport() {
-        return shouldCreatePKSupport;
-    }
-
-    /**
-     * Returns whether DbGenerator is configured to create tables for DataMap 
entities.
-     */
-    public boolean shouldCreateTables() {
-        return shouldCreateTables;
-    }
-
-    public boolean shouldDropPKSupport() {
-        return shouldDropPKSupport;
-    }
-
-    public boolean shouldDropTables() {
-        return shouldDropTables;
-    }
-
-    public boolean shouldCreateFKConstraints() {
-        return shouldCreateFKConstraints;
-    }
-
-    public void setShouldCreatePKSupport(boolean shouldCreatePKSupport) {
-        this.shouldCreatePKSupport = shouldCreatePKSupport;
-    }
-
-    public void setShouldCreateTables(boolean shouldCreateTables) {
-        this.shouldCreateTables = shouldCreateTables;
-    }
-
-    public void setShouldDropPKSupport(boolean shouldDropPKSupport) {
-        this.shouldDropPKSupport = shouldDropPKSupport;
-    }
-
-    public void setShouldDropTables(boolean shouldDropTables) {
-        this.shouldDropTables = shouldDropTables;
-    }
-
-    public void setShouldCreateFKConstraints(boolean 
shouldCreateFKConstraints) {
-        this.shouldCreateFKConstraints = shouldCreateFKConstraints;
-    }
-
-    /**
-     * Returns a DataDomain used by the DbGenerator to detect cross-database
-     * relationships. By default DataDomain is null.
-     * 
-     * @since 1.2
-     */
-    public DataDomain getDomain() {
-        return domain;
-    }
-
-    /**
-     * Helper method that orders DbEntities to satisfy referential constraints 
and returns
-     * an ordered list. It also filters out DerivedDbEntities.
-     */
-    private void prepareDbEntities(Collection<DbEntity> excludedEntities) {
-        if (excludedEntities == null) {
-            excludedEntities = Collections.emptyList();
-        }
-
-        List<DbEntity> tables = new ArrayList<DbEntity>();
-        List<DbEntity> tablesWithAutoPk = new ArrayList<DbEntity>();
-
-        for (DbEntity nextEntity : map.getDbEntities()) {
-
-            // do sanity checks...
-
-            // tables with no columns are not included
-            if (nextEntity.getAttributes().size() == 0) {
-                logObj
-                        .info("Skipping entity with no attributes: "
-                                + nextEntity.getName());
-                continue;
-            }
-
-            // check if this entity is explicitly excluded
-            if (excludedEntities.contains(nextEntity)) {
-                continue;
-            }
-
-            // tables with invalid DbAttributes are not included
-            boolean invalidAttributes = false;
-            for (final DbAttribute attr : nextEntity.getAttributes()) {
-                if (attr.getType() == TypesMapping.NOT_DEFINED) {
-                    logObj.info("Skipping entity, attribute type is undefined: 
"
-                            + nextEntity.getName()
-                            + "."
-                            + attr.getName());
-                    invalidAttributes = true;
-                    break;
-                }
-            }
-            if (invalidAttributes) {
-                continue;
-            }
-
-            tables.add(nextEntity);
-
-            // check if an automatic PK generation can be potentially supported
-            // in this entity. For now simply check that the key is not 
propagated
-            Iterator<DbRelationship> relationships = nextEntity
-                    .getRelationships()
-                    .iterator();
-
-            // create a copy of the original PK list,
-            // since the list will be modified locally
-            List<DbAttribute> pkAttributes = new ArrayList<DbAttribute>(
-                    nextEntity.getPrimaryKeys());
-            while (pkAttributes.size() > 0 && relationships.hasNext()) {
-                DbRelationship nextRelationship = relationships.next();
-                if (!nextRelationship.isToMasterPK()) {
-                    continue;
-                }
-
-                // supposedly all source attributes of the relationship
-                // to master entity must be a part of primary key,
-                // so
-                for (DbJoin join : nextRelationship.getJoins()) {
-                    pkAttributes.remove(join.getSource());
-                }
-            }
-
-            // primary key is needed only if at least one of the primary key 
attributes
-            // is not propagated via relationship
-            if (pkAttributes.size() > 0) {
-                tablesWithAutoPk.add(nextEntity);
-            }
-        }
-
-        // sort table list
-        if (tables.size() > 1) {
-            EntitySorter sorter = new AshwoodEntitySorter();
-            sorter.setEntityResolver(new 
EntityResolver(Collections.singleton(map)));
-            sorter.sortDbEntities(tables, false);
-        }
-
-        this.dbEntitiesInInsertOrder = tables;
-        this.dbEntitiesRequiringAutoPK = tablesWithAutoPk;
-    }
+       private Log logObj = LogFactory.getLog(DbGenerator.class);
+
+       protected DbAdapter adapter;
+       protected DataMap map;
+
+       // optional DataDomain needed for correct FK generation in cross-db
+       // situations
+       protected DataDomain domain;
+
+       protected JdbcEventLogger jdbcEventLogger;
+
+       // stores generated SQL statements
+       protected Map<String, Collection<String>> dropTables;
+       protected Map<String, String> createTables;
+       protected Map<String, List<String>> createConstraints;
+       protected List<String> createPK;
+       protected List<String> dropPK;
+
+       /**
+        * Contains all DbEntities ordered considering their interdependencies.
+        * DerivedDbEntities are filtered out of this list.
+        */
+       protected List<DbEntity> dbEntitiesInInsertOrder;
+       protected List<DbEntity> dbEntitiesRequiringAutoPK;
+
+       protected boolean shouldDropTables;
+       protected boolean shouldCreateTables;
+       protected boolean shouldDropPKSupport;
+       protected boolean shouldCreatePKSupport;
+       protected boolean shouldCreateFKConstraints;
+
+       protected ValidationResult failures;
+
+       /**
+        * @since 3.1
+        */
+       public DbGenerator(DbAdapter adapter, DataMap map, JdbcEventLogger 
logger) {
+               this(adapter, map, logger, Collections.<DbEntity> emptyList());
+       }
+
+       /**
+        * @since 3.1
+        */
+       public DbGenerator(DbAdapter adapter, DataMap map, JdbcEventLogger 
logger, Collection<DbEntity> excludedEntities) {
+               this(adapter, map, excludedEntities, null, logger);
+       }
+
+       /**
+        * Creates and initializes new DbGenerator instance.
+        * 
+        * @param adapter
+        *            DbAdapter corresponding to the database
+        * @param map
+        *            DataMap whose entities will be used in schema generation
+        * @param excludedEntities
+        *            entities that should be ignored during schema generation
+        * @param domain
+        *            optional DataDomain used to detect cross-database
+        *            relationships.
+        * @since 3.1
+        */
+       public DbGenerator(DbAdapter adapter, DataMap map, Collection<DbEntity> 
excludedEntities, DataDomain domain,
+                       JdbcEventLogger logger) {
+               // sanity check
+               if (adapter == null) {
+                       throw new IllegalArgumentException("Adapter must not be 
null.");
+               }
+
+               if (map == null) {
+                       throw new IllegalArgumentException("DataMap must not be 
null.");
+               }
+
+               this.domain = domain;
+               this.map = map;
+               this.adapter = adapter;
+               this.jdbcEventLogger = logger;
+
+               prepareDbEntities(excludedEntities);
+               resetToDefaults();
+               buildStatements();
+       }
+
+       protected void resetToDefaults() {
+               this.shouldDropTables = false;
+               this.shouldDropPKSupport = false;
+               this.shouldCreatePKSupport = true;
+               this.shouldCreateTables = true;
+               this.shouldCreateFKConstraints = true;
+       }
+
+       /**
+        * Creates and stores internally a set of statements for database schema
+        * creation, ignoring configured schema creation preferences. 
Statements are
+        * NOT executed in this method.
+        */
+       protected void buildStatements() {
+               dropTables = new HashMap<String, Collection<String>>();
+               createTables = new HashMap<String, String>();
+               createConstraints = new HashMap<String, List<String>>();
+
+               DbAdapter adapter = getAdapter();
+               for (final DbEntity dbe : this.dbEntitiesInInsertOrder) {
+
+                       String name = dbe.getName();
+
+                       // build "DROP TABLE"
+                       dropTables.put(name, adapter.dropTableStatements(dbe));
+
+                       // build "CREATE TABLE"
+                       createTables.put(name, adapter.createTable(dbe));
+
+                       // build constraints
+                       createConstraints.put(name, 
createConstraintsQueries(dbe));
+               }
+
+               PkGenerator pkGenerator = adapter.getPkGenerator();
+               dropPK = 
pkGenerator.dropAutoPkStatements(dbEntitiesRequiringAutoPK);
+               createPK = 
pkGenerator.createAutoPkStatements(dbEntitiesRequiringAutoPK);
+       }
+
+       /**
+        * Returns <code>true</code> if there is nothing to be done by this
+        * generator. If <code>respectConfiguredSettings</code> is 
<code>true</code>
+        * , checks are done applying currently configured settings, otherwise 
check
+        * is done, assuming that all possible generated objects.
+        */
+       public boolean isEmpty(boolean respectConfiguredSettings) {
+               if (dbEntitiesInInsertOrder.isEmpty() && 
dbEntitiesRequiringAutoPK.isEmpty()) {
+                       return true;
+               }
+
+               if (!respectConfiguredSettings) {
+                       return false;
+               }
+
+               return !(shouldDropTables || shouldCreateTables || 
shouldCreateFKConstraints || shouldCreatePKSupport || shouldDropPKSupport);
+       }
+
+       /** Returns DbAdapter associated with this DbGenerator. */
+       public DbAdapter getAdapter() {
+               return adapter;
+       }
+
+       /**
+        * Returns a list of all schema statements that should be executed with 
the
+        * current configuration.
+        */
+       public List<String> configuredStatements() {
+               List<String> list = new ArrayList<String>();
+
+               if (shouldDropTables) {
+                       ListIterator<DbEntity> it = 
dbEntitiesInInsertOrder.listIterator(dbEntitiesInInsertOrder.size());
+                       while (it.hasPrevious()) {
+                               DbEntity ent = it.previous();
+                               list.addAll(dropTables.get(ent.getName()));
+                       }
+               }
+
+               if (shouldCreateTables) {
+                       for (final DbEntity ent : dbEntitiesInInsertOrder) {
+                               list.add(createTables.get(ent.getName()));
+                       }
+               }
+
+               if (shouldCreateFKConstraints) {
+                       for (final DbEntity ent : dbEntitiesInInsertOrder) {
+                               List<String> fks = 
createConstraints.get(ent.getName());
+                               list.addAll(fks);
+                       }
+               }
+
+               if (shouldDropPKSupport) {
+                       list.addAll(dropPK);
+               }
+
+               if (shouldCreatePKSupport) {
+                       list.addAll(createPK);
+               }
+
+               return list;
+       }
+
+       /**
+        * Creates a temporary DataSource out of DataSourceInfo and invokes
+        * <code>public void runGenerator(DataSource ds)</code>.
+        */
+       public void runGenerator(DataSourceInfo dsi) throws Exception {
+               this.failures = null;
+
+               // do a pre-check. Maybe there is no need to run anything
+               // and therefore no need to create a connection
+               if (isEmpty(true)) {
+                       return;
+               }
+
+               Driver driver = (Driver) 
Class.forName(dsi.getJdbcDriver()).newInstance();
+               DataSource dataSource = new DriverDataSource(driver, 
dsi.getDataSourceUrl(), dsi.getUserName(),
+                               dsi.getPassword(), jdbcEventLogger);
+
+               runGenerator(dataSource);
+       }
+
+       /**
+        * Executes a set of commands to drop/create database objects. This is 
the
+        * main worker method of DbGenerator. Command set is built based on
+        * pre-configured generator settings.
+        */
+       public void runGenerator(DataSource ds) throws Exception {
+               this.failures = null;
+
+               Connection connection = ds.getConnection();
+
+               try {
+
+                       // drop tables
+                       if (shouldDropTables) {
+                               ListIterator<DbEntity> it = 
dbEntitiesInInsertOrder.listIterator(dbEntitiesInInsertOrder.size());
+                               while (it.hasPrevious()) {
+                                       DbEntity ent = it.previous();
+                                       for (String statement : 
dropTables.get(ent.getName())) {
+                                               safeExecute(connection, 
statement);
+                                       }
+                               }
+                       }
+
+                       // create tables
+                       List<String> createdTables = new ArrayList<String>();
+                       if (shouldCreateTables) {
+                               for (final DbEntity ent : 
dbEntitiesInInsertOrder) {
+
+                                       // only create missing tables
+
+                                       safeExecute(connection, 
createTables.get(ent.getName()));
+                                       createdTables.add(ent.getName());
+                               }
+                       }
+
+                       // create FK
+                       if (shouldCreateTables && shouldCreateFKConstraints) {
+                               for (DbEntity ent : dbEntitiesInInsertOrder) {
+
+                                       if 
(createdTables.contains(ent.getName())) {
+                                               List<String> fks = 
createConstraints.get(ent.getName());
+                                               for (String fk : fks) {
+                                                       safeExecute(connection, 
fk);
+                                               }
+                                       }
+                               }
+                       }
+
+                       // drop PK
+                       if (shouldDropPKSupport) {
+                               List<String> dropAutoPKSQL = 
getAdapter().getPkGenerator().dropAutoPkStatements(
+                                               dbEntitiesRequiringAutoPK);
+                               for (final String sql : dropAutoPKSQL) {
+                                       safeExecute(connection, sql);
+                               }
+                       }
+
+                       // create pk
+                       if (shouldCreatePKSupport) {
+                               List<String> createAutoPKSQL = 
getAdapter().getPkGenerator().createAutoPkStatements(
+                                               dbEntitiesRequiringAutoPK);
+                               for (final String sql : createAutoPKSQL) {
+                                       safeExecute(connection, sql);
+                               }
+                       }
+
+                       new DbGeneratorPostprocessor().execute(connection, 
getAdapter());
+               } finally {
+                       connection.close();
+               }
+       }
+
+       /**
+        * Builds and executes a SQL statement, catching and storing SQL 
exceptions
+        * resulting from invalid SQL. Only non-recoverable exceptions are 
rethrown.
+        * 
+        * @since 1.1
+        */
+       protected boolean safeExecute(Connection connection, String sql) throws 
SQLException {
+               Statement statement = connection.createStatement();
+
+               try {
+                       jdbcEventLogger.logQuery(sql, null);
+                       statement.execute(sql);
+                       return true;
+               } catch (SQLException ex) {
+                       if (this.failures == null) {
+                               this.failures = new ValidationResult();
+                       }
+
+                       failures.addFailure(new SimpleValidationFailure(sql, 
ex.getMessage()));
+                       jdbcEventLogger.logQueryError(ex);
+                       return false;
+               } finally {
+                       statement.close();
+               }
+       }
+
+       /**
+        * Creates FK and UNIQUE constraint statements for a given table.
+        * 
+        * @since 3.0
+        */
+       public List<String> createConstraintsQueries(DbEntity table) {
+               List<String> list = new ArrayList<String>();
+               for (final DbRelationship rel : table.getRelationships()) {
+
+                       if (rel.isToMany()) {
+                               continue;
+                       }
+
+                       // skip FK to a different DB
+                       if (domain != null) {
+                               DataMap srcMap = 
rel.getSourceEntity().getDataMap();
+                               DataMap targetMap = 
rel.getTargetEntity().getDataMap();
+
+                               if (srcMap != null && targetMap != null && 
srcMap != targetMap) {
+                                       if (domain.lookupDataNode(srcMap) != 
domain.lookupDataNode(targetMap)) {
+                                               continue;
+                                       }
+                               }
+                       }
+
+                       // create an FK CONSTRAINT only if the relationship is 
to PK
+                       // and if this is not a dependent PK
+
+                       // create UNIQUE CONSTRAINT on FK if reverse 
relationship is to-one
+
+                       if (rel.isToPK() && !rel.isToDependentPK()) {
+
+                               if (getAdapter().supportsUniqueConstraints()) {
+
+                                       DbRelationship reverse = 
rel.getReverseRelationship();
+                                       if (reverse != null && 
!reverse.isToMany() && !reverse.isToPK()) {
+
+                                               String unique = 
getAdapter().createUniqueConstraint((DbEntity) rel.getSourceEntity(),
+                                                               
rel.getSourceAttributes());
+                                               if (unique != null) {
+                                                       list.add(unique);
+                                               }
+                                       }
+                               }
+
+                               String fk = 
getAdapter().createFkConstraint(rel);
+                               if (fk != null) {
+                                       list.add(fk);
+                               }
+                       }
+               }
+               return list;
+       }
+
+       /**
+        * Returns an object representing a collection of failures that 
occurred on
+        * the last "runGenerator" invocation, or null if there were no 
failures.
+        * Failures usually indicate problems with generated DDL (such as
+        * "create...", "drop...", etc.) and usually happen due to the DataMap 
being
+        * out of sync with the database.
+        * 
+        * @since 1.1
+        */
+       public ValidationResult getFailures() {
+               return failures;
+       }
+
+       /**
+        * Returns whether DbGenerator is configured to create primary key 
support
+        * for DataMap entities.
+        */
+       public boolean shouldCreatePKSupport() {
+               return shouldCreatePKSupport;
+       }
+
+       /**
+        * Returns whether DbGenerator is configured to create tables for 
DataMap
+        * entities.
+        */
+       public boolean shouldCreateTables() {
+               return shouldCreateTables;
+       }
+
+       public boolean shouldDropPKSupport() {
+               return shouldDropPKSupport;
+       }
+
+       public boolean shouldDropTables() {
+               return shouldDropTables;
+       }
+
+       public boolean shouldCreateFKConstraints() {
+               return shouldCreateFKConstraints;
+       }
+
+       public void setShouldCreatePKSupport(boolean shouldCreatePKSupport) {
+               this.shouldCreatePKSupport = shouldCreatePKSupport;
+       }
+
+       public void setShouldCreateTables(boolean shouldCreateTables) {
+               this.shouldCreateTables = shouldCreateTables;
+       }
+
+       public void setShouldDropPKSupport(boolean shouldDropPKSupport) {
+               this.shouldDropPKSupport = shouldDropPKSupport;
+       }
+
+       public void setShouldDropTables(boolean shouldDropTables) {
+               this.shouldDropTables = shouldDropTables;
+       }
+
+       public void setShouldCreateFKConstraints(boolean 
shouldCreateFKConstraints) {
+               this.shouldCreateFKConstraints = shouldCreateFKConstraints;
+       }
+
+       /**
+        * Returns a DataDomain used by the DbGenerator to detect cross-database
+        * relationships. By default DataDomain is null.
+        * 
+        * @since 1.2
+        */
+       public DataDomain getDomain() {
+               return domain;
+       }
+
+       /**
+        * Helper method that orders DbEntities to satisfy referential 
constraints
+        * and returns an ordered list. It also filters out DerivedDbEntities.
+        */
+       private void prepareDbEntities(Collection<DbEntity> excludedEntities) {
+               if (excludedEntities == null) {
+                       excludedEntities = Collections.emptyList();
+               }
+
+               List<DbEntity> tables = new ArrayList<DbEntity>();
+               List<DbEntity> tablesWithAutoPk = new ArrayList<DbEntity>();
+
+               for (DbEntity nextEntity : map.getDbEntities()) {
+
+                       // do sanity checks...
+
+                       // tables with no columns are not included
+                       if (nextEntity.getAttributes().size() == 0) {
+                               logObj.info("Skipping entity with no 
attributes: " + nextEntity.getName());
+                               continue;
+                       }
+
+                       // check if this entity is explicitly excluded
+                       if (excludedEntities.contains(nextEntity)) {
+                               continue;
+                       }
+
+                       // tables with invalid DbAttributes are not included
+                       boolean invalidAttributes = false;
+                       for (final DbAttribute attr : 
nextEntity.getAttributes()) {
+                               if (attr.getType() == TypesMapping.NOT_DEFINED) 
{
+                                       logObj.info("Skipping entity, attribute 
type is undefined: " + nextEntity.getName() + "."
+                                                       + attr.getName());
+                                       invalidAttributes = true;
+                                       break;
+                               }
+                       }
+                       if (invalidAttributes) {
+                               continue;
+                       }
+
+                       tables.add(nextEntity);
+
+                       // check if an automatic PK generation can be 
potentially supported
+                       // in this entity. For now simply check that the key is 
not
+                       // propagated
+                       Iterator<DbRelationship> relationships = 
nextEntity.getRelationships().iterator();
+
+                       // create a copy of the original PK list,
+                       // since the list will be modified locally
+                       List<DbAttribute> pkAttributes = new 
ArrayList<DbAttribute>(nextEntity.getPrimaryKeys());
+                       while (pkAttributes.size() > 0 && 
relationships.hasNext()) {
+                               DbRelationship nextRelationship = 
relationships.next();
+                               if (!nextRelationship.isToMasterPK()) {
+                                       continue;
+                               }
+
+                               // supposedly all source attributes of the 
relationship
+                               // to master entity must be a part of primary 
key,
+                               // so
+                               for (DbJoin join : nextRelationship.getJoins()) 
{
+                                       pkAttributes.remove(join.getSource());
+                               }
+                       }
+
+                       // primary key is needed only if at least one of the 
primary key
+                       // attributes
+                       // is not propagated via relationship
+                       if (pkAttributes.size() > 0) {
+                               tablesWithAutoPk.add(nextEntity);
+                       }
+               }
+
+               // sort table list
+               if (tables.size() > 1) {
+                       EntitySorter sorter = new AshwoodEntitySorter();
+                       sorter.setEntityResolver(new 
EntityResolver(Collections.singleton(map)));
+                       sorter.sortDbEntities(tables, false);
+               }
+
+               this.dbEntitiesInInsertOrder = tables;
+               this.dbEntitiesRequiringAutoPK = tablesWithAutoPk;
+       }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/12e83f21/cayenne-server/src/main/java/org/apache/cayenne/datasource/DataSourceBuilder.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/datasource/DataSourceBuilder.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/datasource/DataSourceBuilder.java
index a2659db..4576f61 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/datasource/DataSourceBuilder.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/datasource/DataSourceBuilder.java
@@ -121,9 +121,7 @@ public class DataSourceBuilder {
 
        private DataSource buildNonPooling() {
                Driver driver = objectFactory.newInstance(Driver.class, 
this.driver);
-               DriverDataSource dataSource = new DriverDataSource(driver, url, 
userName, password);
-               dataSource.setLogger(logger);
-               return dataSource;
+               return new DriverDataSource(driver, url, userName, password, 
logger);
        }
 
        private PoolingDataSource buildPooling(DataSource nonPoolingDataSource) 
{

http://git-wip-us.apache.org/repos/asf/cayenne/blob/12e83f21/cayenne-server/src/main/java/org/apache/cayenne/datasource/DriverDataSource.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/datasource/DriverDataSource.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/datasource/DriverDataSource.java
index 3dda4b4..2f9ba1c 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/datasource/DriverDataSource.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/datasource/DriverDataSource.java
@@ -32,6 +32,7 @@ import javax.sql.DataSource;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.log.JdbcEventLogger;
+import org.apache.cayenne.log.NoopJdbcEventLogger;
 import org.apache.cayenne.util.Util;
 
 /**
@@ -78,8 +79,9 @@ public class DriverDataSource implements DataSource {
         * registering the driver. "connectionUrl" on the other hand must NOT be
         * null.
         * 
-        * @deprecated since 4.0 as class loading should not happen here. Use
-        *             {@link #DriverDataSource(Driver, String, String, 
String)}.
+        * @deprecated since 4.0 as class loading should not happen here. Use {
+        *             {@link #DriverDataSource(Driver, String, String, String, 
JdbcEventLogger)}
+        *             .
         */
        @Deprecated
        public DriverDataSource(String driverClassName, String connectionUrl) {
@@ -94,16 +96,29 @@ public class DriverDataSource implements DataSource {
         * null.
         * 
         * @deprecated since 4.0 as class loading should not happen here. Use
-        *             {@link #DriverDataSource(Driver, String, String, 
String)}.
+        *             {@link #DriverDataSource(Driver, String, String, String, 
JdbcEventLogger)}
+        *             .
         */
        @Deprecated
        public DriverDataSource(String driverClassName, String connectionUrl, 
String userName, String password) {
-
                this(loadDriver(driverClassName), connectionUrl, userName, 
password);
+       }
 
-               this.connectionUrl = connectionUrl;
-               this.userName = userName;
-               this.password = password;
+       /**
+        * Creates a DriverDataSource wrapping a given Driver. If "driver" is 
null,
+        * DriverDataSource will consult DriverManager for a registered driver 
for
+        * the given URL. So when specifying null, a user must take care of
+        * registering the driver. "connectionUrl" on the other hand must NOT be
+        * null.
+        * 
+        * @since 1.1
+        * @deprecated since 4.0 as class loading should not happen here. Use
+        *             {@link #DriverDataSource(Driver, String, String, String, 
JdbcEventLogger)}
+        *             .
+        */
+       @Deprecated
+       public DriverDataSource(Driver driver, String connectionUrl, String 
userName, String password) {
+               this(driver, connectionUrl, userName, password, 
NoopJdbcEventLogger.getInstance());
        }
 
        /**
@@ -113,14 +128,24 @@ public class DriverDataSource implements DataSource {
         * registering the driver. "connectionUrl" on the other hand must NOT be
         * null.
         * 
-        * @since 1.1
+        * @since 4.0
         */
-       public DriverDataSource(Driver driver, String connectionUrl, String 
userName, String password) {
+       public DriverDataSource(Driver driver, String connectionUrl, String 
userName, String password,
+                       JdbcEventLogger logger) {
+
+               if (connectionUrl == null) {
+                       throw new NullPointerException("Null 'connectionUrl'");
+               }
+
+               if (logger == null) {
+                       throw new NullPointerException("Null 'logger'");
+               }
 
                this.driver = driver;
                this.connectionUrl = connectionUrl;
                this.userName = userName;
                this.password = password;
+               this.logger = logger;
        }
 
        /**
@@ -196,52 +221,80 @@ public class DriverDataSource implements DataSource {
                DriverManager.setLogWriter(out);
        }
 
+       /**
+        * @deprecated since 4.0. Connection parameters are immutable and not
+        *             readable.
+        */
+       @Deprecated
        public JdbcEventLogger getLogger() {
                return logger;
        }
 
-       public void setLogger(JdbcEventLogger delegate) {
-               logger = delegate;
+       /**
+        * @deprecated since 4.0. Logger is immutable.
+        */
+       @Deprecated
+       public void setLogger(JdbcEventLogger logger) {
+               if (logger == null) {
+                       throw new NullPointerException("Null 'logger'");
+               }
+
+               this.logger = logger;
        }
 
        /**
         * @since 3.0
+        * @deprecated since 4.0. Connection parameters are immutable and not
+        *             readable.
         */
+       @Deprecated
        public String getConnectionUrl() {
                return connectionUrl;
        }
 
        /**
         * @since 3.0
+        * @deprecated since 4.0. Connection parameters are immutable.
         */
+       @Deprecated
        public void setConnectionUrl(String connectionUrl) {
                this.connectionUrl = connectionUrl;
        }
 
        /**
         * @since 3.0
+        * @deprecated since 4.0. Connection parameters are immutable and not
+        *             readable.
         */
+       @Deprecated
        public String getPassword() {
                return password;
        }
 
        /**
+        * @deprecated since 4.0. Connection parameters are immutable.
         * @since 3.0
         */
+       @Deprecated
        public void setPassword(String password) {
                this.password = password;
        }
 
        /**
         * @since 3.0
+        * @deprecated since 4.0. Connection parameters are immutable and not
+        *             readable.
         */
+       @Deprecated
        public String getUserName() {
                return userName;
        }
 
        /**
         * @since 3.0
+        * @deprecated since 4.0. Connection parameters are immutable.
         */
+       @Deprecated
        public void setUserName(String userName) {
                this.userName = userName;
        }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/12e83f21/cayenne-server/src/test/java/org/apache/cayenne/datasource/BasePoolingDataSourceIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/datasource/BasePoolingDataSourceIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/datasource/BasePoolingDataSourceIT.java
index 22d8421..4e54aa1 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/datasource/BasePoolingDataSourceIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/datasource/BasePoolingDataSourceIT.java
@@ -52,8 +52,7 @@ public class BasePoolingDataSourceIT extends ServerCase {
 
                Driver driver = objectFactory.newInstance(Driver.class, 
dataSourceInfo.getJdbcDriver());
                DriverDataSource nonPooling = new DriverDataSource(driver, 
dataSourceInfo.getDataSourceUrl(),
-                               dataSourceInfo.getUserName(), 
dataSourceInfo.getPassword());
-               nonPooling.setLogger(logger);
+                               dataSourceInfo.getUserName(), 
dataSourceInfo.getPassword(), logger);
 
                PoolingDataSourceParameters poolParameters = createParameters();
                this.dataSource = new PoolingDataSource(nonPooling, 
poolParameters);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/12e83f21/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSource_FailingValidationQueryIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSource_FailingValidationQueryIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSource_FailingValidationQueryIT.java
index 7f7d854..c7e666e 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSource_FailingValidationQueryIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/datasource/PoolingDataSource_FailingValidationQueryIT.java
@@ -22,8 +22,6 @@ import java.sql.Driver;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.conn.DataSourceInfo;
-import org.apache.cayenne.datasource.PoolingDataSource;
-import org.apache.cayenne.datasource.PoolingDataSourceParameters;
 import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.log.JdbcEventLogger;
@@ -57,8 +55,7 @@ public class PoolingDataSource_FailingValidationQueryIT 
extends ServerCase {
        public void testConstructor() throws Exception {
                Driver driver = objectFactory.newInstance(Driver.class, 
dataSourceInfo.getJdbcDriver());
                DriverDataSource nonPooling = new DriverDataSource(driver, 
dataSourceInfo.getDataSourceUrl(),
-                               dataSourceInfo.getUserName(), 
dataSourceInfo.getPassword());
-               nonPooling.setLogger(logger);
+                               dataSourceInfo.getUserName(), 
dataSourceInfo.getPassword(), logger);
 
                PoolingDataSourceParameters poolParameters = createParameters();
                new PoolingDataSource(nonPooling, poolParameters);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/12e83f21/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbGeneratorTask.java
----------------------------------------------------------------------
diff --git 
a/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbGeneratorTask.java 
b/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbGeneratorTask.java
index 634213b..c02b811 100644
--- a/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbGeneratorTask.java
+++ b/cayenne-tools/src/main/java/org/apache/cayenne/tools/DbGeneratorTask.java
@@ -45,111 +45,110 @@ import org.apache.tools.ant.Project;
 // TODO: support classpath attribute for loading the driver
 public class DbGeneratorTask extends CayenneTask {
 
-    // DbGenerator options... setup defaults similar to DbGenerator itself:
-    // all DROP set to false, all CREATE - to true
-    protected boolean dropTables;
-    protected boolean dropPK;
-    protected boolean createTables = true;
-    protected boolean createPK = true;
-    protected boolean createFK = true;
-
-    @Override
-    public void execute() {
-
-        Log logger = new AntLogger(this);
-       
-
-        log(String.format("connection settings - [driver: %s, url: %s, 
username: %s]", driver, url, userName),
-                Project.MSG_VERBOSE);
-
-        log(String.format(
-                "generator options - [dropTables: %s, dropPK: %s, 
createTables: %s, createPK: %s, createFK: %s]",
-                dropTables, dropPK, createTables, createPK, createFK), 
Project.MSG_VERBOSE);
-
-        validateAttributes();
-
-        ClassLoader loader = null;
-        Injector injector = DIBootstrap.createInjector(new 
ToolsModule(logger));
-        try {
-            loader = Thread.currentThread().getContextClassLoader();
-            
Thread.currentThread().setContextClassLoader(DbGeneratorTask.class.getClassLoader());
-
-            // Load the data map and run the db generator.
-            DataMap dataMap = loadDataMap();
-
-            // load driver taking custom CLASSPATH into account...
-            DriverDataSource dataSource = new DriverDataSource((Driver) 
Class.forName(driver).newInstance(), url,
-                    userName, password);
-
-            DbAdapter adapter = getAdapter(injector, dataSource);
-
-            DbGenerator generator = new DbGenerator(adapter, dataMap, 
Collections.<DbEntity> emptyList(), null,
-                    NoopJdbcEventLogger.getInstance());
-            generator.setShouldCreateFKConstraints(createFK);
-            generator.setShouldCreatePKSupport(createPK);
-            generator.setShouldCreateTables(createTables);
-            generator.setShouldDropPKSupport(dropPK);
-            generator.setShouldDropTables(dropTables);
-
-            generator.runGenerator(dataSource);
-        } catch (Exception ex) {
-            Throwable th = Util.unwindException(ex);
-
-            String message = "Error generating database";
-
-            if (th.getLocalizedMessage() != null) {
-                message += ": " + th.getLocalizedMessage();
-            }
-
-            log(message, Project.MSG_ERR);
-            throw new BuildException(message, th);
-        } finally {
-            Thread.currentThread().setContextClassLoader(loader);
-            injector.shutdown();
-        }
-    }
-
-    /**
-     * Validates attributes that are not related to internal
-     * DefaultClassGenerator. Throws BuildException if attributes are invalid.
-     */
-    protected void validateAttributes() throws BuildException {
-        StringBuilder error = new StringBuilder("");
-
-        if (map == null) {
-            error.append("The 'map' attribute must be set.\n");
-        }
-
-        if (driver == null) {
-            error.append("The 'driver' attribute must be set.\n");
-        }
-
-        if (url == null) {
-            error.append("The 'adapter' attribute must be set.\n");
-        }
-
-        if (error.length() > 0) {
-            throw new BuildException(error.toString());
-        }
-    }
-
-    public void setCreateFK(boolean createFK) {
-        this.createFK = createFK;
-    }
-
-    public void setCreatePK(boolean createPK) {
-        this.createPK = createPK;
-    }
-
-    public void setCreateTables(boolean createTables) {
-        this.createTables = createTables;
-    }
-
-    public void setDropPK(boolean dropPK) {
-        this.dropPK = dropPK;
-    }
-
-    public void setDropTables(boolean dropTables) {
-        this.dropTables = dropTables;
-    }
+       // DbGenerator options... setup defaults similar to DbGenerator itself:
+       // all DROP set to false, all CREATE - to true
+       protected boolean dropTables;
+       protected boolean dropPK;
+       protected boolean createTables = true;
+       protected boolean createPK = true;
+       protected boolean createFK = true;
+
+       @Override
+       public void execute() {
+
+               Log logger = new AntLogger(this);
+
+               log(String.format("connection settings - [driver: %s, url: %s, 
username: %s]", driver, url, userName),
+                               Project.MSG_VERBOSE);
+
+               log(String.format(
+                               "generator options - [dropTables: %s, dropPK: 
%s, createTables: %s, createPK: %s, createFK: %s]",
+                               dropTables, dropPK, createTables, createPK, 
createFK), Project.MSG_VERBOSE);
+
+               validateAttributes();
+
+               ClassLoader loader = null;
+               Injector injector = DIBootstrap.createInjector(new 
ToolsModule(logger));
+               try {
+                       loader = Thread.currentThread().getContextClassLoader();
+                       
Thread.currentThread().setContextClassLoader(DbGeneratorTask.class.getClassLoader());
+
+                       // Load the data map and run the db generator.
+                       DataMap dataMap = loadDataMap();
+
+                       // load driver taking custom CLASSPATH into account...
+                       DriverDataSource dataSource = new 
DriverDataSource((Driver) Class.forName(driver).newInstance(), url,
+                                       userName, password, 
NoopJdbcEventLogger.getInstance());
+
+                       DbAdapter adapter = getAdapter(injector, dataSource);
+
+                       DbGenerator generator = new DbGenerator(adapter, 
dataMap, Collections.<DbEntity> emptyList(), null,
+                                       NoopJdbcEventLogger.getInstance());
+                       generator.setShouldCreateFKConstraints(createFK);
+                       generator.setShouldCreatePKSupport(createPK);
+                       generator.setShouldCreateTables(createTables);
+                       generator.setShouldDropPKSupport(dropPK);
+                       generator.setShouldDropTables(dropTables);
+
+                       generator.runGenerator(dataSource);
+               } catch (Exception ex) {
+                       Throwable th = Util.unwindException(ex);
+
+                       String message = "Error generating database";
+
+                       if (th.getLocalizedMessage() != null) {
+                               message += ": " + th.getLocalizedMessage();
+                       }
+
+                       log(message, Project.MSG_ERR);
+                       throw new BuildException(message, th);
+               } finally {
+                       Thread.currentThread().setContextClassLoader(loader);
+                       injector.shutdown();
+               }
+       }
+
+       /**
+        * Validates attributes that are not related to internal
+        * DefaultClassGenerator. Throws BuildException if attributes are 
invalid.
+        */
+       protected void validateAttributes() throws BuildException {
+               StringBuilder error = new StringBuilder("");
+
+               if (map == null) {
+                       error.append("The 'map' attribute must be set.\n");
+               }
+
+               if (driver == null) {
+                       error.append("The 'driver' attribute must be set.\n");
+               }
+
+               if (url == null) {
+                       error.append("The 'adapter' attribute must be set.\n");
+               }
+
+               if (error.length() > 0) {
+                       throw new BuildException(error.toString());
+               }
+       }
+
+       public void setCreateFK(boolean createFK) {
+               this.createFK = createFK;
+       }
+
+       public void setCreatePK(boolean createPK) {
+               this.createPK = createPK;
+       }
+
+       public void setCreateTables(boolean createTables) {
+               this.createTables = createTables;
+       }
+
+       public void setDropPK(boolean dropPK) {
+               this.dropPK = dropPK;
+       }
+
+       public void setDropTables(boolean dropTables) {
+               this.dropTables = dropTables;
+       }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/12e83f21/cayenne-tools/src/main/java/org/apache/cayenne/tools/configuration/DriverDataSourceFactory.java
----------------------------------------------------------------------
diff --git 
a/cayenne-tools/src/main/java/org/apache/cayenne/tools/configuration/DriverDataSourceFactory.java
 
b/cayenne-tools/src/main/java/org/apache/cayenne/tools/configuration/DriverDataSourceFactory.java
index 56c1a05..e80159d 100644
--- 
a/cayenne-tools/src/main/java/org/apache/cayenne/tools/configuration/DriverDataSourceFactory.java
+++ 
b/cayenne-tools/src/main/java/org/apache/cayenne/tools/configuration/DriverDataSourceFactory.java
@@ -28,26 +28,29 @@ import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.datasource.DriverDataSource;
 import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.log.JdbcEventLogger;
 
 /**
  * @since 4.0
  */
 public class DriverDataSourceFactory implements DataSourceFactory {
 
-    private AdhocObjectFactory objectFactory;
+       private AdhocObjectFactory objectFactory;
+       private JdbcEventLogger logger;
 
-    public DriverDataSourceFactory(@Inject AdhocObjectFactory objectFactory) {
-        this.objectFactory = objectFactory;
-    }
+       public DriverDataSourceFactory(@Inject AdhocObjectFactory 
objectFactory, @Inject JdbcEventLogger logger) {
+               this.objectFactory = objectFactory;
+               this.logger = logger;
+       }
 
-    public DataSource getDataSource(DataNodeDescriptor nodeDescriptor) throws 
Exception {
-        DataSourceInfo properties = nodeDescriptor.getDataSourceDescriptor();
-        if (properties == null) {
-            throw new IllegalArgumentException("'nodeDescriptor' contains no 
datasource descriptor");
-        }
+       public DataSource getDataSource(DataNodeDescriptor nodeDescriptor) 
throws Exception {
+               DataSourceInfo properties = 
nodeDescriptor.getDataSourceDescriptor();
+               if (properties == null) {
+                       throw new IllegalArgumentException("'nodeDescriptor' 
contains no datasource descriptor");
+               }
 
-        Driver driver = objectFactory.newInstance(Driver.class, 
properties.getJdbcDriver());
-        return new DriverDataSource(driver, properties.getDataSourceUrl(), 
properties.getUserName(),
-                properties.getPassword());
-    }
+               Driver driver = objectFactory.newInstance(Driver.class, 
properties.getJdbcDriver());
+               return new DriverDataSource(driver, 
properties.getDataSourceUrl(), properties.getUserName(),
+                               properties.getPassword(), logger);
+       }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/12e83f21/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/DataSourcePreferences.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/DataSourcePreferences.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/DataSourcePreferences.java
index 1092624..712f13a 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/DataSourcePreferences.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/pref/DataSourcePreferences.java
@@ -37,6 +37,7 @@ import javax.swing.DefaultComboBoxModel;
 import javax.swing.JOptionPane;
 
 import org.apache.cayenne.datasource.DriverDataSource;
+import org.apache.cayenne.log.NoopJdbcEventLogger;
 import org.apache.cayenne.modeler.FileClassLoadingService;
 import org.apache.cayenne.modeler.pref.DBConnectionInfo;
 import org.apache.cayenne.modeler.util.CayenneController;
@@ -54,287 +55,254 @@ import org.apache.commons.collections.Transformer;
  */
 public class DataSourcePreferences extends CayenneController {
 
-    protected DataSourcePreferencesView view;
-    protected String dataSourceKey;
-    protected Map dataSources;
-    protected ChildrenMapPreference dataSourcePreferences;
-    protected CayennePreferenceEditor editor;
-
-    public DataSourcePreferences(PreferenceDialog parentController) {
-        super(parentController);
-
-        this.view = new DataSourcePreferencesView(this);
-
-        PreferenceEditor editor = parentController.getEditor();
-        if (editor instanceof CayennePreferenceEditor) {
-            this.editor = (CayennePreferenceEditor) editor;
-        }
-
-        // init view data
-        this.dataSourcePreferences = getApplication()
-                .getCayenneProjectPreferences()
-                .getDetailObject(DBConnectionInfo.class);
-        this.dataSources = dataSourcePreferences.getChildrenPreferences();
-
-        Object[] keys = dataSources.keySet().toArray();
-        Arrays.sort(keys);
-        DefaultComboBoxModel dataSourceModel = new DefaultComboBoxModel(keys);
-        view.getDataSources().setModel(dataSourceModel);
-
-        initBindings();
-
-        // show first item
-        if (keys.length > 0) {
-            view.getDataSources().setSelectedIndex(0);
-            editDataSourceAction();
-        }
-    }
-
-    public Component getView() {
-        return view;
-    }
-
-    protected void initBindings() {
-        BindingBuilder builder = new BindingBuilder(
-                getApplication().getBindingFactory(),
-                this);
-        builder.bindToAction(view.getAddDataSource(), "newDataSourceAction()");
-        builder
-                .bindToAction(
-                        view.getDuplicateDataSource(),
-                        "duplicateDataSourceAction()");
-        builder.bindToAction(view.getRemoveDataSource(), 
"removeDataSourceAction()");
-        builder.bindToAction(view.getTestDataSource(), 
"testDataSourceAction()");
-
-        builder.bindToComboSelection(view.getDataSources(), "dataSourceKey");
-    }
-
-    public Map getDataSources() {
-        return dataSources;
-    }
-
-    public String getDataSourceKey() {
-        return dataSourceKey;
-    }
-
-    public void setDataSourceKey(String dataSourceKey) {
-        this.dataSourceKey = dataSourceKey;
-        editDataSourceAction();
-    }
-
-    public DBConnectionInfo getConnectionInfo() {
-        return (DBConnectionInfo) 
dataSourcePreferences.getObject(dataSourceKey);
-    }
-
-    /**
-     * Shows a dialog to create new local DataSource configuration.
-     */
-    public void newDataSourceAction() {
-
-        DataSourceCreator creatorWizard = new DataSourceCreator(this);
-        DBConnectionInfo dataSource = creatorWizard.startupAction();
-
-        if (dataSource != null) {
-            dataSourcePreferences.create(creatorWizard.getName(), dataSource);
-            dataSources = dataSourcePreferences.getChildrenPreferences();
-
-            Object[] keys = dataSources.keySet().toArray();
-            Arrays.sort(keys);
-            view.getDataSources().setModel(new DefaultComboBoxModel(keys));
-            view.getDataSources().setSelectedItem(creatorWizard.getName());
-            editDataSourceAction();
-        }
-    }
-
-    /**
-     * Shows a dialog to duplicate an existing local DataSource configuration.
-     */
-    public void duplicateDataSourceAction() {
-        Object selected = view.getDataSources().getSelectedItem();
-        if (selected != null) {
-            DataSourceDuplicator wizard = new DataSourceDuplicator(this, 
selected
-                    .toString());
-            DBConnectionInfo dataSource = wizard.startupAction();
-
-            if (dataSource != null) {
-                dataSourcePreferences.create(wizard.getName(), dataSource);
-                dataSources = dataSourcePreferences.getChildrenPreferences();
-
-                Object[] keys = dataSources.keySet().toArray();
-                Arrays.sort(keys);
-                view.getDataSources().setModel(new DefaultComboBoxModel(keys));
-                view.getDataSources().setSelectedItem(wizard.getName());
-                editDataSourceAction();
-            }
-        }
-    }
-
-    /**
-     * Removes current DataSource.
-     */
-    public void removeDataSourceAction() {
-        String key = getDataSourceKey();
-        if (key != null) {
-            dataSourcePreferences.remove(key);
-
-            dataSources = dataSourcePreferences.getChildrenPreferences();
-            Object[] keys = dataSources.keySet().toArray();
-            Arrays.sort(keys);
-            view.getDataSources().setModel(new DefaultComboBoxModel(keys));
-            editDataSourceAction(keys.length > 0 ? keys[0] : null);
-        }
-    }
-
-    /**
-     * Opens specified DataSource in the editor.
-     */
-    public void editDataSourceAction(Object dataSourceKey) {
-        view.getDataSources().setSelectedItem(dataSourceKey);
-        editDataSourceAction();
-    }
-
-    /**
-     * Opens current DataSource in the editor.
-     */
-    public void editDataSourceAction() {
-        this.view.getDataSourceEditor().setConnectionInfo(getConnectionInfo());
-    }
-
-    /**
-     * Tries to establish a DB connection, reporting the status of this 
operation.
-     */
-    public void testDataSourceAction() {
-        DBConnectionInfo currentDataSource = getConnectionInfo();
-        if (currentDataSource == null) {
-            return;
-        }
-
-        if (currentDataSource.getJdbcDriver() == null) {
-            JOptionPane.showMessageDialog(
-                    null,
-                    "No JDBC Driver specified",
-                    "Warning",
-                    JOptionPane.WARNING_MESSAGE);
-            return;
-        }
-
-        if (currentDataSource.getUrl() == null) {
-            JOptionPane.showMessageDialog(
-                    null,
-                    "No Database URL specified",
-                    "Warning",
-                    JOptionPane.WARNING_MESSAGE);
-            return;
-        }
-
-        try {
-
-            FileClassLoadingService classLoader = new 
FileClassLoadingService();
-
-            List<File> oldPathFiles = ((FileClassLoadingService) 
getApplication()
-                    .getClassLoadingService()).getPathFiles();
-
-            Collection details = new ArrayList<String>();
-            for (int i = 0; i < oldPathFiles.size(); i++) {
-                details.add(oldPathFiles.get(i).getAbsolutePath());
-            }
-
-            Preferences classPathPreferences = 
getApplication().getPreferencesNode(
-                    ClasspathPreferences.class,
-                    "");
-            if 
(editor.getChangedPreferences().containsKey(classPathPreferences)) {
-                Map<String, String> map = editor.getChangedPreferences().get(
-                        classPathPreferences);
-
-                Iterator iterator = map.entrySet().iterator();
-                while (iterator.hasNext()) {
-                    Map.Entry en = (Map.Entry) iterator.next();
-                    String key = (String) en.getKey();
-                    if (!details.contains(key)) {
-                        details.add(key);
-                    }
-                }
-            }
-
-            if 
(editor.getRemovedPreferences().containsKey(classPathPreferences)) {
-                Map<String, String> map = editor.getRemovedPreferences().get(
-                        classPathPreferences);
-
-                Iterator iterator = map.entrySet().iterator();
-                while (iterator.hasNext()) {
-                    Map.Entry en = (Map.Entry) iterator.next();
-                    String key = (String) en.getKey();
-                    if (details.contains(key)) {
-                        details.remove(key);
-                    }
-                }
-            }
-
-            if (details.size() > 0) {
-
-                // transform preference to file...
-                Transformer transformer = new Transformer() {
-
-                    public Object transform(Object object) {
-                        String pref = (String) object;
-                        return new File(pref);
-                    }
-                };
-
-                classLoader.setPathFiles(CollectionUtils.collect(details, 
transformer));
-            }
-
-            Class<Driver> driverClass = classLoader.loadClass(
-                    Driver.class,
-                    currentDataSource.getJdbcDriver());
-            Driver driver = driverClass.newInstance();
-
-            // connect via Cayenne DriverDataSource - it addresses some driver 
issues...
-            Connection c = new DriverDataSource(
-                    driver,
-                    currentDataSource.getUrl(),
-                    currentDataSource.getUserName(),
-                    currentDataSource.getPassword()).getConnection();
-            try {
-                c.close();
-            }
-            catch (SQLException e) {
-                // i guess we can ignore this...
-            }
-
-            JOptionPane.showMessageDialog(
-                    null,
-                    "Connected Successfully",
-                    "Success",
-                    JOptionPane.INFORMATION_MESSAGE);
-        }
-        catch (Throwable th) {
-            th = Util.unwindException(th);
-            String message = "Error connecting to DB: " + 
th.getLocalizedMessage();
-
-            StringTokenizer st = new StringTokenizer(message);
-            StringBuilder sbMessage = new StringBuilder();
-            int len = 0;
-
-            String tempString;
-            while (st.hasMoreTokens()) {
-                tempString = st.nextElement().toString();
-                if (len < 110) {
-                    len = len + tempString.length() + 1;
-                }
-                else {
-                    sbMessage.append("\n");
-                    len = 0;
-                }
-                sbMessage.append(tempString + " ");
-            }
-
-            JOptionPane.showMessageDialog(
-                    null,
-                    sbMessage.toString(),
-                    "Warning",
-                    JOptionPane.WARNING_MESSAGE);
-            return;
-        }
-    }
+       protected DataSourcePreferencesView view;
+       protected String dataSourceKey;
+       protected Map dataSources;
+       protected ChildrenMapPreference dataSourcePreferences;
+       protected CayennePreferenceEditor editor;
+
+       public DataSourcePreferences(PreferenceDialog parentController) {
+               super(parentController);
+
+               this.view = new DataSourcePreferencesView(this);
+
+               PreferenceEditor editor = parentController.getEditor();
+               if (editor instanceof CayennePreferenceEditor) {
+                       this.editor = (CayennePreferenceEditor) editor;
+               }
+
+               // init view data
+               this.dataSourcePreferences = 
getApplication().getCayenneProjectPreferences().getDetailObject(
+                               DBConnectionInfo.class);
+               this.dataSources = 
dataSourcePreferences.getChildrenPreferences();
+
+               Object[] keys = dataSources.keySet().toArray();
+               Arrays.sort(keys);
+               DefaultComboBoxModel dataSourceModel = new 
DefaultComboBoxModel(keys);
+               view.getDataSources().setModel(dataSourceModel);
+
+               initBindings();
+
+               // show first item
+               if (keys.length > 0) {
+                       view.getDataSources().setSelectedIndex(0);
+                       editDataSourceAction();
+               }
+       }
+
+       public Component getView() {
+               return view;
+       }
+
+       protected void initBindings() {
+               BindingBuilder builder = new 
BindingBuilder(getApplication().getBindingFactory(), this);
+               builder.bindToAction(view.getAddDataSource(), 
"newDataSourceAction()");
+               builder.bindToAction(view.getDuplicateDataSource(), 
"duplicateDataSourceAction()");
+               builder.bindToAction(view.getRemoveDataSource(), 
"removeDataSourceAction()");
+               builder.bindToAction(view.getTestDataSource(), 
"testDataSourceAction()");
+
+               builder.bindToComboSelection(view.getDataSources(), 
"dataSourceKey");
+       }
+
+       public Map getDataSources() {
+               return dataSources;
+       }
+
+       public String getDataSourceKey() {
+               return dataSourceKey;
+       }
+
+       public void setDataSourceKey(String dataSourceKey) {
+               this.dataSourceKey = dataSourceKey;
+               editDataSourceAction();
+       }
+
+       public DBConnectionInfo getConnectionInfo() {
+               return (DBConnectionInfo) 
dataSourcePreferences.getObject(dataSourceKey);
+       }
+
+       /**
+        * Shows a dialog to create new local DataSource configuration.
+        */
+       public void newDataSourceAction() {
+
+               DataSourceCreator creatorWizard = new DataSourceCreator(this);
+               DBConnectionInfo dataSource = creatorWizard.startupAction();
+
+               if (dataSource != null) {
+                       dataSourcePreferences.create(creatorWizard.getName(), 
dataSource);
+                       dataSources = 
dataSourcePreferences.getChildrenPreferences();
+
+                       Object[] keys = dataSources.keySet().toArray();
+                       Arrays.sort(keys);
+                       view.getDataSources().setModel(new 
DefaultComboBoxModel(keys));
+                       
view.getDataSources().setSelectedItem(creatorWizard.getName());
+                       editDataSourceAction();
+               }
+       }
+
+       /**
+        * Shows a dialog to duplicate an existing local DataSource 
configuration.
+        */
+       public void duplicateDataSourceAction() {
+               Object selected = view.getDataSources().getSelectedItem();
+               if (selected != null) {
+                       DataSourceDuplicator wizard = new 
DataSourceDuplicator(this, selected.toString());
+                       DBConnectionInfo dataSource = wizard.startupAction();
+
+                       if (dataSource != null) {
+                               dataSourcePreferences.create(wizard.getName(), 
dataSource);
+                               dataSources = 
dataSourcePreferences.getChildrenPreferences();
+
+                               Object[] keys = dataSources.keySet().toArray();
+                               Arrays.sort(keys);
+                               view.getDataSources().setModel(new 
DefaultComboBoxModel(keys));
+                               
view.getDataSources().setSelectedItem(wizard.getName());
+                               editDataSourceAction();
+                       }
+               }
+       }
+
+       /**
+        * Removes current DataSource.
+        */
+       public void removeDataSourceAction() {
+               String key = getDataSourceKey();
+               if (key != null) {
+                       dataSourcePreferences.remove(key);
+
+                       dataSources = 
dataSourcePreferences.getChildrenPreferences();
+                       Object[] keys = dataSources.keySet().toArray();
+                       Arrays.sort(keys);
+                       view.getDataSources().setModel(new 
DefaultComboBoxModel(keys));
+                       editDataSourceAction(keys.length > 0 ? keys[0] : null);
+               }
+       }
+
+       /**
+        * Opens specified DataSource in the editor.
+        */
+       public void editDataSourceAction(Object dataSourceKey) {
+               view.getDataSources().setSelectedItem(dataSourceKey);
+               editDataSourceAction();
+       }
+
+       /**
+        * Opens current DataSource in the editor.
+        */
+       public void editDataSourceAction() {
+               
this.view.getDataSourceEditor().setConnectionInfo(getConnectionInfo());
+       }
+
+       /**
+        * Tries to establish a DB connection, reporting the status of this
+        * operation.
+        */
+       public void testDataSourceAction() {
+               DBConnectionInfo currentDataSource = getConnectionInfo();
+               if (currentDataSource == null) {
+                       return;
+               }
+
+               if (currentDataSource.getJdbcDriver() == null) {
+                       JOptionPane.showMessageDialog(null, "No JDBC Driver 
specified", "Warning", JOptionPane.WARNING_MESSAGE);
+                       return;
+               }
+
+               if (currentDataSource.getUrl() == null) {
+                       JOptionPane.showMessageDialog(null, "No Database URL 
specified", "Warning", JOptionPane.WARNING_MESSAGE);
+                       return;
+               }
+
+               try {
+
+                       FileClassLoadingService classLoader = new 
FileClassLoadingService();
+
+                       List<File> oldPathFiles = ((FileClassLoadingService) 
getApplication().getClassLoadingService())
+                                       .getPathFiles();
+
+                       Collection details = new ArrayList<String>();
+                       for (int i = 0; i < oldPathFiles.size(); i++) {
+                               
details.add(oldPathFiles.get(i).getAbsolutePath());
+                       }
+
+                       Preferences classPathPreferences = 
getApplication().getPreferencesNode(ClasspathPreferences.class, "");
+                       if 
(editor.getChangedPreferences().containsKey(classPathPreferences)) {
+                               Map<String, String> map = 
editor.getChangedPreferences().get(classPathPreferences);
+
+                               Iterator iterator = map.entrySet().iterator();
+                               while (iterator.hasNext()) {
+                                       Map.Entry en = (Map.Entry) 
iterator.next();
+                                       String key = (String) en.getKey();
+                                       if (!details.contains(key)) {
+                                               details.add(key);
+                                       }
+                               }
+                       }
+
+                       if 
(editor.getRemovedPreferences().containsKey(classPathPreferences)) {
+                               Map<String, String> map = 
editor.getRemovedPreferences().get(classPathPreferences);
+
+                               Iterator iterator = map.entrySet().iterator();
+                               while (iterator.hasNext()) {
+                                       Map.Entry en = (Map.Entry) 
iterator.next();
+                                       String key = (String) en.getKey();
+                                       if (details.contains(key)) {
+                                               details.remove(key);
+                                       }
+                               }
+                       }
+
+                       if (details.size() > 0) {
+
+                               // transform preference to file...
+                               Transformer transformer = new Transformer() {
+
+                                       public Object transform(Object object) {
+                                               String pref = (String) object;
+                                               return new File(pref);
+                                       }
+                               };
+
+                               
classLoader.setPathFiles(CollectionUtils.collect(details, transformer));
+                       }
+
+                       Class<Driver> driverClass = 
classLoader.loadClass(Driver.class, currentDataSource.getJdbcDriver());
+                       Driver driver = driverClass.newInstance();
+
+                       // connect via Cayenne DriverDataSource - it addresses 
some driver
+                       // issues...
+                       Connection c = new DriverDataSource(driver, 
currentDataSource.getUrl(), currentDataSource.getUserName(),
+                                       currentDataSource.getPassword(), 
NoopJdbcEventLogger.getInstance()).getConnection();
+                       try {
+                               c.close();
+                       } catch (SQLException e) {
+                               // i guess we can ignore this...
+                       }
+
+                       JOptionPane.showMessageDialog(null, "Connected 
Successfully", "Success", JOptionPane.INFORMATION_MESSAGE);
+               } catch (Throwable th) {
+                       th = Util.unwindException(th);
+                       String message = "Error connecting to DB: " + 
th.getLocalizedMessage();
+
+                       StringTokenizer st = new StringTokenizer(message);
+                       StringBuilder sbMessage = new StringBuilder();
+                       int len = 0;
+
+                       String tempString;
+                       while (st.hasMoreTokens()) {
+                               tempString = st.nextElement().toString();
+                               if (len < 110) {
+                                       len = len + tempString.length() + 1;
+                               } else {
+                                       sbMessage.append("\n");
+                                       len = 0;
+                               }
+                               sbMessage.append(tempString + " ");
+                       }
+
+                       JOptionPane.showMessageDialog(null, 
sbMessage.toString(), "Warning", JOptionPane.WARNING_MESSAGE);
+                       return;
+               }
+       }
 }

Reply via email to