You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2016/09/29 18:54:23 UTC

cayenne git commit: CAY-2115 DbLoader - allow loading DataMap without Obj layer

Repository: cayenne
Updated Branches:
  refs/heads/master 2f7b1d533 -> 184d455fa


CAY-2115 DbLoader - allow loading DataMap without Obj layer

... preliminary work ...

* DbLoader cleanup and refactoring, removal of deprecated methods (will be breaking backwards compatibility)
* Squashing Connection leaks in ReverseEngineeringController


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

Branch: refs/heads/master
Commit: 184d455fa7990d506d6973c7c49a4376475ed882
Parents: 2f7b1d5
Author: Andrus Adamchik <an...@objectstyle.com>
Authored: Thu Sep 29 21:11:25 2016 +0300
Committer: Andrus Adamchik <an...@objectstyle.com>
Committed: Thu Sep 29 21:54:05 2016 +0300

----------------------------------------------------------------------
 .../apache/cayenne/dbsync/reverse/DbLoader.java |  94 +------
 .../cayenne/dbsync/reverse/DbLoaderIT.java      |  44 ++--
 .../dbsync/reverse/DbLoaderPartialIT.java       | 116 ---------
 .../tools/dbimport/DefaultDbImportAction.java   |   8 +-
 .../modeler/dialog/db/DbLoaderHelper.java       |  11 -
 .../dialog/db/ModelerDbImportAction.java        |   1 -
 .../modeler/dialog/db/ModelerDbLoader.java      | 258 +++++++++++++++++++
 .../dialog/db/ReverseEngineeringController.java | 257 ++----------------
 8 files changed, 313 insertions(+), 476 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/184d455f/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/DbLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/DbLoader.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/DbLoader.java
index a6f286a..aa36434 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/DbLoader.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/DbLoader.java
@@ -20,9 +20,9 @@ package org.apache.cayenne.dbsync.reverse;
 
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.TypesMapping;
+import org.apache.cayenne.dbsync.merge.EntityMergeSupport;
 import org.apache.cayenne.dbsync.reverse.filters.CatalogFilter;
 import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
-import org.apache.cayenne.dbsync.reverse.filters.PatternFilter;
 import org.apache.cayenne.dbsync.reverse.filters.SchemaFilter;
 import org.apache.cayenne.dbsync.reverse.filters.TableFilter;
 import org.apache.cayenne.map.DataMap;
@@ -39,7 +39,6 @@ import org.apache.cayenne.map.naming.ExportedKey;
 import org.apache.cayenne.map.naming.LegacyNameGenerator;
 import org.apache.cayenne.map.naming.NameCheckers;
 import org.apache.cayenne.map.naming.ObjectNameGenerator;
-import org.apache.cayenne.dbsync.merge.EntityMergeSupport;
 import org.apache.cayenne.util.EqualsBuilder;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -68,8 +67,7 @@ public class DbLoader {
 
 	private static final Log LOGGER = LogFactory.getLog(DbLoader.class);
 
-	public static final String WILDCARD = "%";
-	public static final String WILDCARD_PATTERN = ".*";
+	private static final String WILDCARD = "%";
 
 	private final Connection connection;
 	private final DbAdapter adapter;
@@ -150,25 +148,7 @@ public class DbLoader {
 	public boolean isCreatingMeaningfulPK() {
 		return creatingMeaningfulPK;
 	}
-
-	/**
-	 * Returns database connection used by this DbLoader.
-	 *
-	 * @since 3.0
-	 */
-	public Connection getConnection() {
-		return connection;
-	}
-
-	/**
-	 * Returns DbAdapter associated with this DbLoader.
-	 *
-	 * @since 1.1
-	 */
-	public DbAdapter getAdapter() {
-		return adapter;
-	}
-
+	
 	/**
 	 * Retrieves catalogs for the database associated with this DbLoader.
 	 *
@@ -512,50 +492,6 @@ public class DbLoader {
 	}
 
 	/**
-	 * Performs database reverse engineering and generates DataMap that contains
-	 * default mapping of the tables and views. By default will include regular
-	 * tables and views.
-	 *
-	 * @since 1.0.7
-	 * @deprecated since 4.0 use
-	 *             {@link #load(DataMap, DbLoaderConfiguration)}
-	 *             method that supports catalogs.
-	 */
-	@Deprecated
-	public DataMap loadDataMapFromDB(String schemaPattern, String tablePattern, DataMap dataMap) throws SQLException {
-
-		DbLoaderConfiguration configuration = new DbLoaderConfiguration();
-		configuration.setFiltersConfig(FiltersConfig.create(null, schemaPattern, TableFilter.include(tablePattern),
-				PatternFilter.INCLUDE_NOTHING));
-
-		load(dataMap, configuration);
-		return dataMap;
-	}
-
-	/**
-	 * Performs database reverse engineering and generates DataMap object that
-	 * contains default mapping of the tables and views. Allows to limit types
-	 * of tables to read.
-	 *
-	 * @deprecated since 4.0 use
-	 *             {@link #load(DataMap, DbLoaderConfiguration)}
-	 *             method that supports catalogs.
-	 */
-	@Deprecated
-	public DataMap loadDataMapFromDB(String schemaPattern, String tablePattern, String[] tableTypes, DataMap dataMap)
-			throws SQLException {
-		dataMap.clear();
-
-		DbLoaderConfiguration config = new DbLoaderConfiguration();
-		config.setFiltersConfig(FiltersConfig.create(null, schemaPattern, TableFilter.include(tablePattern),
-				PatternFilter.INCLUDE_NOTHING));
-		config.setTableTypes(tableTypes);
-
-		load(dataMap, config);
-		return dataMap;
-	}
-
-	/**
 	 * Performs database reverse engineering based on the specified config and
 	 * fills the specified DataMap object with DB and object mapping info.
 	 *
@@ -589,7 +525,7 @@ public class DbLoader {
 				schema, getMetaData(), adapter, filter));
 	}
 
-	public void prepareObjLayer(DataMap dataMap, DbLoaderConfiguration config, Collection<DbEntity> entities) {
+	private void prepareObjLayer(DataMap dataMap, DbLoaderConfiguration config, Collection<DbEntity> entities) {
 		Collection<ObjEntity> loadedObjEntities = loadObjEntities(dataMap, config, entities);
 		flattenManyToManyRelationships(dataMap, loadedObjEntities, getNameGenerator());
 		fireObjEntitiesAddedEvents(loadedObjEntities);
@@ -620,28 +556,6 @@ public class DbLoader {
 	 * be invoked explicitly by the user. </i>
 	 * </p>
 	 *
-	 * @since 1.1
-	 * @deprecated since 4.0 use loadProcedures(DataMap, String, String, String)
-	 *             that supports "catalog" pattern.
-	 */
-	@Deprecated
-	public void loadProceduresFromDB(String schemaPattern, String namePattern, DataMap dataMap) throws SQLException {
-		DbLoaderConfiguration configuration = new DbLoaderConfiguration();
-		configuration.setFiltersConfig(FiltersConfig.create(null, schemaPattern, TableFilter.everything(),
-				new PatternFilter().include(namePattern)));
-
-		loadProcedures(dataMap, configuration);
-	}
-
-	/**
-	 * Loads database stored procedures into the DataMap.
-	 * <p>
-	 * <i>As of 1.1 there is no boolean property or delegate method to make
-	 * procedure loading optional or to implement custom merging logic, so
-	 * currently this method is NOT CALLED from "loadDataMapFromDB" and should
-	 * be invoked explicitly by the user. </i>
-	 * </p>
-	 *
 	 * @since 4.0
 	 */
 	public Map<String, Procedure> loadProcedures(DataMap dataMap, DbLoaderConfiguration config) throws SQLException {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/184d455f/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/DbLoaderIT.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/DbLoaderIT.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/DbLoaderIT.java
index a902754..93539ed 100644
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/DbLoaderIT.java
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/DbLoaderIT.java
@@ -36,6 +36,7 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.sql.Connection;
 import java.sql.Types;
 import java.util.Collection;
 import java.util.List;
@@ -60,14 +61,31 @@ public class DbLoaderIT extends ServerCase {
 
     private DbLoader loader;
 
+    private Connection connection;
+
+    private static String msgForTypeMismatch(DbAttribute origAttr, DbAttribute newAttr) {
+        return msgForTypeMismatch(origAttr.getType(), newAttr);
+    }
+
+    private static String msgForTypeMismatch(int origType, DbAttribute newAttr) {
+        String nt = TypesMapping.getSqlNameByType(newAttr.getType());
+        String ot = TypesMapping.getSqlNameByType(origType);
+        return attrMismatch(newAttr.getName(), "expected type: <" + ot + ">, but was <" + nt + ">");
+    }
+
+    private static String attrMismatch(String attrName, String msg) {
+        return "[Error loading attribute '" + attrName + "': " + msg + "]";
+    }
+
     @Before
-    public void setUp() throws Exception {
-        loader = new DbLoader(dataSourceFactory.getSharedDataSource().getConnection(), adapter, null);
+    public void before() throws Exception {
+        this.connection = dataSourceFactory.getSharedDataSource().getConnection();
+        this.loader = new DbLoader(connection, adapter, null);
     }
 
     @After
-    public void tearDown() throws Exception {
-        loader.getConnection().close();
+    public void after() throws Exception {
+        connection.close();
     }
 
     @Test
@@ -118,7 +136,7 @@ public class DbLoaderIT extends ServerCase {
                 FiltersConfig.create("WRONG", null, TableFilter.everything(), PatternFilter.INCLUDE_NOTHING));
         List<DetectedDbEntity> tables = loader
                 .createTableLoader("WRONG", null, TableFilter.everything())
-                    .getDbEntities(TableFilter.everything(), new String[]{adapter.tableTypeForTable()});
+                .getDbEntities(TableFilter.everything(), new String[]{adapter.tableTypeForTable()});
 
         assertNotNull(tables);
         assertTrue(tables.isEmpty());
@@ -142,7 +160,7 @@ public class DbLoaderIT extends ServerCase {
     public void testLoadWithMeaningfulPK() throws Exception {
 
         DataMap map = new DataMap();
-        String[] tableLabel = { adapter.tableTypeForTable() };
+        String[] tableLabel = {adapter.tableTypeForTable()};
 
         loader.setCreatingMeaningfulPK(true);
 
@@ -413,18 +431,4 @@ public class DbLoaderIT extends ServerCase {
             }
         }
     }
-
-    private static String msgForTypeMismatch(DbAttribute origAttr, DbAttribute newAttr) {
-        return msgForTypeMismatch(origAttr.getType(), newAttr);
-    }
-
-    private static String msgForTypeMismatch(int origType, DbAttribute newAttr) {
-        String nt = TypesMapping.getSqlNameByType(newAttr.getType());
-        String ot = TypesMapping.getSqlNameByType(origType);
-        return attrMismatch(newAttr.getName(), "expected type: <" + ot + ">, but was <" + nt + ">");
-    }
-
-    private static String attrMismatch(String attrName, String msg) {
-        return "[Error loading attribute '" + attrName + "': " + msg + "]";
-    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/184d455f/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/DbLoaderPartialIT.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/DbLoaderPartialIT.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/DbLoaderPartialIT.java
deleted file mode 100644
index 5490ef9..0000000
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/reverse/DbLoaderPartialIT.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*****************************************************************
- *   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.
- ****************************************************************/
-
-package org.apache.cayenne.dbsync.reverse;
-
-import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.unit.di.server.CayenneProjects;
-import org.apache.cayenne.unit.di.server.ServerCase;
-import org.apache.cayenne.unit.di.server.ServerCaseDataSourceFactory;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Collection;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-@UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
-public class DbLoaderPartialIT extends ServerCase {
-
-    @Inject
-    private DbAdapter adapter;
-
-    @Inject
-    private ServerCaseDataSourceFactory dataSourceFactory;
-
-    private DbLoader loader;
-
-    @Before
-    public void setUp() throws Exception {
-        loader = new DbLoader(
-                dataSourceFactory.getSharedDataSource().getConnection(),
-                adapter,
-                new DefaultDbLoaderDelegate());
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        loader.getConnection().close();
-    }
-
-    /**
-     * Tests that FKs are properly loaded when the relationship source is not loaded. See
-     * CAY-479. This test will perform two reverse engineers. The second reverse engineer
-     * will skip two tables that share relationships with PAINTING. Relationships in
-     * ARTIST and GALLERY should remain unmodified, and all PAINTING relationships should
-     * be loaded.
-     */
-    @Test
-    public void testPartialLoad() throws Exception {
-
-        DataMap map = new DataMap();
-        String tableLabel = adapter.tableTypeForTable();
-
-        loader.loadDataMapFromDB(null, "%", new String[] {tableLabel}, map);
-
-        Collection<?> rels = getDbEntity(map, "ARTIST").getRelationships();
-        assertNotNull(rels);
-        int artistRels = rels.size();
-
-        rels = getDbEntity(map, "GALLERY").getRelationships();
-        assertNotNull(rels);
-        int galleryRels = rels.size();
-
-        rels = getDbEntity(map, "PAINTING").getRelationships();
-        assertNotNull(rels);
-        int paintingRels = rels.size();
-
-        loader.loadDataMapFromDB(null, "%", new String[] {
-            tableLabel
-        }, map);
-
-        rels = getDbEntity(map, "ARTIST").getRelationships();
-        assertNotNull(rels);
-        assertEquals(artistRels, rels.size());
-
-        rels = getDbEntity(map, "GALLERY").getRelationships();
-        assertNotNull(rels);
-        assertEquals(galleryRels, rels.size());
-
-        rels = getDbEntity(map, "PAINTING").getRelationships();
-        assertNotNull(rels);
-        assertEquals(paintingRels, rels.size());
-    }
-
-    private DbEntity getDbEntity(DataMap map, String name) {
-        DbEntity de = map.getDbEntity(name);
-        // sometimes table names get converted to lowercase
-        if (de == null) {
-            de = map.getDbEntity(name.toLowerCase());
-        }
-
-        return de;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/184d455f/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java
----------------------------------------------------------------------
diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java
index d344946..2eeb664 100644
--- a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java
+++ b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java
@@ -230,12 +230,12 @@ public class DefaultDbImportAction implements DbImportAction {
 
         MergerContext mergerContext = MergerContext.builder(dataMap).delegate(mergeDelegate).build();
 
-        for (MergerToken tok : tokens) {
+        for (MergerToken token : tokens) {
             try {
-                tok.execute(mergerContext);
+                token.execute(mergerContext);
             } catch (Throwable th) {
-                String message = "Migration Error. Can't apply changes from token: " + tok.getTokenName()
-                        + " (" + tok.getTokenValue() + ")";
+                String message = "Migration Error. Can't apply changes from token: " + token.getTokenName()
+                        + " (" + token.getTokenValue() + ")";
 
                 logger.error(message, th);
                 mergerContext.getValidationResult().addFailure(new SimpleValidationFailure(th, message));

http://git-wip-us.apache.org/repos/asf/cayenne/blob/184d455f/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java
index 92123c0..55b166f 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbLoaderHelper.java
@@ -163,7 +163,6 @@ public class DbLoaderHelper {
 
     protected void processException(final Throwable th, final String message) {
         logObj.info("Exception on reverse engineering", Util.unwindException(th));
-        cleanup();
         SwingUtilities.invokeLater(new Runnable() {
 
             public void run() {
@@ -173,16 +172,6 @@ public class DbLoaderHelper {
         });
     }
 
-    protected void cleanup() {
-        loadStatusNote = "Closing connection...";
-        try {
-            if (loader.getConnection() != null) {
-                loader.getConnection().close();
-            }
-        } catch (SQLException e) {
-            logObj.warn("Error closing connection.", e);
-        }
-    }
 
     private final class LoaderDelegate extends DefaultDbLoaderDelegate {
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/184d455f/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbImportAction.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbImportAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbImportAction.java
index b7e6ce2..b51af57 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbImportAction.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbImportAction.java
@@ -81,7 +81,6 @@ public class ModelerDbImportAction implements DbImportAction {
 
             @Override
             protected void saveLoaded(DataMap dataMap) {
-                dbLoaderHelper.cleanup();
 
                 ProjectController mediator = dbLoaderHelper.getMediator();
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/184d455f/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbLoader.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbLoader.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbLoader.java
new file mode 100644
index 0000000..15d15b0
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ModelerDbLoader.java
@@ -0,0 +1,258 @@
+/*****************************************************************
+ *   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.
+ ****************************************************************/
+package org.apache.cayenne.modeler.dialog.db;
+
+import org.apache.cayenne.dbsync.reverse.DbLoader;
+import org.apache.cayenne.dbsync.reverse.DbLoaderConfiguration;
+import org.apache.cayenne.dbsync.reverse.DefaultDbLoaderDelegate;
+import org.apache.cayenne.dbsync.reverse.filters.CatalogFilter;
+import org.apache.cayenne.dbsync.reverse.filters.SchemaFilter;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.Procedure;
+import org.apache.cayenne.modeler.dialog.db.model.DBCatalog;
+import org.apache.cayenne.modeler.dialog.db.model.DBColumn;
+import org.apache.cayenne.modeler.dialog.db.model.DBElement;
+import org.apache.cayenne.modeler.dialog.db.model.DBEntity;
+import org.apache.cayenne.modeler.dialog.db.model.DBModel;
+import org.apache.cayenne.modeler.dialog.db.model.DBProcedure;
+import org.apache.cayenne.modeler.dialog.db.model.DBSchema;
+import org.apache.cayenne.modeler.dialog.pref.TreeEditor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+
+// TODO: rewrite this whole thing...
+class ModelerDbLoader extends DbLoader {
+
+    private static final Log LOGGER = LogFactory.getLog(ModelerDbLoader.class);
+
+    private TreeEditor treeEditor;
+    private ReverseEngineeringController reverseEngineeringController;
+
+    public ModelerDbLoader(ReverseEngineeringController reverseEngineeringController, TreeEditor treeEditor, Connection connection) {
+        super(connection, reverseEngineeringController.adapter, new DefaultDbLoaderDelegate());
+        this.treeEditor = treeEditor;
+        this.reverseEngineeringController = reverseEngineeringController;
+    }
+
+    @Override
+    public DataMap load(DbLoaderConfiguration config) throws SQLException {
+        DataMap dataMap = new DataMap();
+        Map<String, Procedure> procedureMap = loadProcedures(dataMap, config);
+        load(dataMap, config);
+        addProcedures(procedureMap);
+        return dataMap;
+    }
+
+    @Override
+    public void load(DataMap dataMap, DbLoaderConfiguration config) throws SQLException {
+        LOGGER.info("Schema loading...");
+
+        String[] types = config.getTableTypes();
+        if (types == null || types.length == 0) {
+            types = getDefaultTableTypes();
+        }
+        boolean isNullDetected = false;
+        for (CatalogFilter catalog : config.getFiltersConfig().catalogs) {
+            for (SchemaFilter schema : catalog.schemas) {
+                if (schema.name == null && catalog.name == null) {
+                    isNullDetected = true;
+                }
+            }
+        }
+        if (isNullDetected) {
+            createIfNull(dataMap, config, types);
+        } else {
+            createIfNotNull(dataMap, config, types);
+        }
+    }
+
+    private void addProcedures(Map<String, Procedure> procedureMap) throws SQLException {
+        DBElement currentDBCatalog;
+        DBElement currentDBSchema;
+        for (Map.Entry<String, Procedure> procedure : procedureMap.entrySet()) {
+            if (supportCatalogs()) {
+                String dbCatalogName = procedure.getValue().getCatalog();
+                DBElement dbCatalog = reverseEngineeringController.dbModel.getExistingElement(dbCatalogName);
+                if (dbCatalog != null) {
+                    currentDBCatalog = dbCatalog;
+                } else {
+                    currentDBCatalog = new DBCatalog(dbCatalogName);
+                    reverseEngineeringController.dbModel.addElement(currentDBCatalog);
+                }
+                if (supportSchemas()) {
+                    String dbSchemaName = procedure.getValue().getSchema();
+                    DBElement dbSchema = currentDBCatalog.getExistingElement(dbSchemaName);
+                    if (dbSchema != null) {
+                        currentDBSchema = dbSchema;
+                    } else {
+                        currentDBSchema = new DBSchema(dbSchemaName);
+                        currentDBCatalog.addElement(currentDBSchema);
+                    }
+                    DBProcedure currentProcedure = new DBProcedure(procedure.getValue().getName());
+                    currentDBSchema.addElement(currentProcedure);
+                } else {
+                    DBProcedure currentProcedure = new DBProcedure(procedure.getValue().getName());
+                    currentDBCatalog.addElement(currentProcedure);
+                }
+            } else if (supportSchemas()) {
+                String dbSchemaName = procedure.getValue().getSchema();
+                DBElement dbSchema = reverseEngineeringController.dbModel.getExistingElement(dbSchemaName);
+                if (dbSchema != null) {
+                    currentDBSchema = dbSchema;
+                } else {
+                    currentDBSchema = new DBSchema(dbSchemaName);
+                    reverseEngineeringController.dbModel.addElement(currentDBSchema);
+                }
+                DBProcedure currentProcedure = new DBProcedure(procedure.getValue().getName());
+                currentDBSchema.addElement(currentProcedure);
+            }
+        }
+    }
+
+    private void createIfNotNull(DataMap dataMap, DbLoaderConfiguration config,
+                                 String[] types) throws SQLException {
+        treeEditor.setRoot(reverseEngineeringController.dataSourceKey);
+        reverseEngineeringController.dbModel = new DBModel(reverseEngineeringController.dataSourceKey);
+        boolean catalogSetted = false;
+        DBElement currentDBCatalog = null;
+        DBElement currentDBSchema = null;
+
+        for (CatalogFilter catalog : config.getFiltersConfig().catalogs) {
+            for (SchemaFilter schema : catalog.schemas) {
+                List<DbEntity> entityList =
+                        createTableLoader(catalog.name, schema.name, schema.tables)
+                                .loadDbEntities(dataMap, config, types);
+                DbEntity entityFromLoader = entityList.get(0);
+
+                if (entityFromLoader != null) {
+                    if (!catalogSetted && entityFromLoader.getCatalog() != null) {
+                        currentDBCatalog = new DBCatalog(entityFromLoader.getCatalog());
+                        reverseEngineeringController.dbModel.addElement(currentDBCatalog);
+                        catalogSetted = true;
+                    }
+
+                    if (entityFromLoader.getSchema() != null) {
+                        currentDBSchema = new DBSchema(entityFromLoader.getSchema());
+                        if (currentDBCatalog != null) {
+                            currentDBCatalog.addElement(currentDBSchema);
+                        } else {
+                            reverseEngineeringController.dbModel.addElement(currentDBSchema);
+                        }
+                    }
+                }
+
+                DBEntity currentDBEntity;
+                if (currentDBSchema != null) {
+                    for (DbEntity dbEntity : entityList) {
+                        currentDBEntity = new DBEntity(dbEntity.getName());
+                        currentDBSchema.addElement(currentDBEntity);
+                        for (DbAttribute dbColumn : dbEntity.getAttributes()) {
+                            currentDBEntity.addElement(new DBColumn(dbColumn.getName()));
+                        }
+                    }
+                } else {
+                    for (DbEntity dbEntity : entityList) {
+                        currentDBEntity = new DBEntity(dbEntity.getName());
+                        for (DbAttribute dbColumn : dbEntity.getAttributes()) {
+                            currentDBEntity.addElement(new DBColumn(dbColumn.getName()));
+                        }
+                        currentDBCatalog.addElement(currentDBEntity);
+                    }
+                }
+                currentDBSchema = null;
+            }
+            catalogSetted = false;
+            currentDBCatalog = null;
+        }
+    }
+
+    private void createIfNull(DataMap dataMap, DbLoaderConfiguration config,
+                              String[] types) throws SQLException {
+
+        treeEditor.setRoot(reverseEngineeringController.dataSourceKey);
+        reverseEngineeringController.dbModel = new DBModel(reverseEngineeringController.dataSourceKey);
+        DBElement currentDBCatalog;
+        DBElement currentDBSchema;
+
+        for (CatalogFilter catalog : config.getFiltersConfig().catalogs) {
+            for (SchemaFilter schema : catalog.schemas) {
+                List<DbEntity> entityList =
+                        createTableLoader(catalog.name, schema.name, schema.tables)
+                                .loadDbEntities(dataMap, config, types);
+
+                for (DbEntity dbEntity : entityList) {
+                    if (supportCatalogs()) {
+                        String dbCatalogName = dbEntity.getCatalog();
+                        DBElement dbCatalog = reverseEngineeringController.dbModel.getExistingElement(dbCatalogName);
+                        if (dbCatalog != null) {
+                            currentDBCatalog = dbCatalog;
+                        } else {
+                            currentDBCatalog = new DBCatalog(dbCatalogName);
+                            reverseEngineeringController.dbModel.addElement(currentDBCatalog);
+                        }
+                        if (supportSchemas()) {
+                            String dbSchemaName = dbEntity.getSchema();
+                            DBElement dbSchema = currentDBCatalog.getExistingElement(dbSchemaName);
+                            if (dbSchema != null) {
+                                currentDBSchema = dbSchema;
+                            } else {
+                                currentDBSchema = new DBSchema(dbSchemaName);
+                                currentDBCatalog.addElement(currentDBSchema);
+                            }
+                            DBEntity currentDBEntity = new DBEntity(dbEntity.getName());
+                            currentDBSchema.addElement(currentDBEntity);
+                            for (DbAttribute dbColumn : dbEntity.getAttributes()) {
+                                currentDBEntity.addElement(new DBColumn(dbColumn.getName()));
+                            }
+                        } else {
+                            DBEntity currentDBEntity = new DBEntity(dbEntity.getName());
+                            currentDBCatalog.addElement(currentDBEntity);
+                            for (DbAttribute dbColumn : dbEntity.getAttributes()) {
+                                currentDBEntity.addElement(new DBColumn(dbColumn.getName()));
+                            }
+                        }
+                    } else {
+                        if (supportSchemas()) {
+                            String dbSchemaName = dbEntity.getSchema();
+                            DBElement dbSchema = reverseEngineeringController.dbModel.getExistingElement(dbSchemaName);
+                            if (dbSchema != null) {
+                                currentDBSchema = dbSchema;
+                            } else {
+                                currentDBSchema = new DBSchema(dbSchemaName);
+                                reverseEngineeringController.dbModel.addElement(currentDBSchema);
+                            }
+                            DBEntity currentDBEntity = new DBEntity(dbEntity.getName());
+                            currentDBSchema.addElement(currentDBEntity);
+                            for (DbAttribute dbColumn : dbEntity.getAttributes()) {
+                                currentDBEntity.addElement(new DBColumn(dbColumn.getName()));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/184d455f/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ReverseEngineeringController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ReverseEngineeringController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ReverseEngineeringController.java
index e83a36a..da5dc7a 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ReverseEngineeringController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/ReverseEngineeringController.java
@@ -22,23 +22,10 @@ import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dbimport.ReverseEngineering;
 import org.apache.cayenne.dbsync.reverse.DbLoader;
 import org.apache.cayenne.dbsync.reverse.DbLoaderConfiguration;
-import org.apache.cayenne.dbsync.reverse.DefaultDbLoaderDelegate;
 import org.apache.cayenne.dbsync.reverse.FiltersConfigBuilder;
-import org.apache.cayenne.dbsync.reverse.filters.CatalogFilter;
-import org.apache.cayenne.dbsync.reverse.filters.SchemaFilter;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.Procedure;
 import org.apache.cayenne.modeler.ClassLoadingService;
 import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.modeler.dialog.db.model.DBCatalog;
-import org.apache.cayenne.modeler.dialog.db.model.DBColumn;
-import org.apache.cayenne.modeler.dialog.db.model.DBElement;
-import org.apache.cayenne.modeler.dialog.db.model.DBEntity;
 import org.apache.cayenne.modeler.dialog.db.model.DBModel;
-import org.apache.cayenne.modeler.dialog.db.model.DBProcedure;
-import org.apache.cayenne.modeler.dialog.db.model.DBSchema;
 import org.apache.cayenne.modeler.dialog.pref.PreferenceDialog;
 import org.apache.cayenne.modeler.dialog.pref.TreeEditor;
 import org.apache.cayenne.modeler.dialog.pref.XMLFileEditor;
@@ -49,13 +36,13 @@ import org.apache.cayenne.swing.ObjectBinding;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import javax.sql.DataSource;
 import javax.swing.*;
 import java.awt.*;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.Arrays;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -63,14 +50,15 @@ import java.util.Map;
  * reverse engineering. Also they can see tree view of db objects clicking on sync button.
  */
 public class ReverseEngineeringController extends CayenneController {
-    private static final Log LOGGER = LogFactory.getLog(ReverseEngineeringController.class);
+
+    private static Log LOGGER = LogFactory.getLog(ReverseEngineeringController.class);
 
     protected ProjectController projectController;
     protected ReverseEngineeringView view;
     protected Map<String, DataMapViewModel> reverseEngineeringMap;
     protected DBModel dbModel;
 
-    protected Connection connection;
+    protected DataSource dataSource;
     protected DbAdapter adapter;
 
     protected DBConnectionInfo connectionInfo;
@@ -103,7 +91,8 @@ public class ReverseEngineeringController extends CayenneController {
 
     private void buildDBProperties() throws Exception {
         ClassLoadingService classLoader = getApplication().getClassLoadingService();
-        this.connection = connectionInfo.makeDataSource(classLoader).getConnection();
+
+        this.dataSource = connectionInfo.makeDataSource(classLoader);
         this.adapter = connectionInfo.makeAdapter(classLoader);
     }
 
@@ -114,215 +103,16 @@ public class ReverseEngineeringController extends CayenneController {
         try {
             buildDBProperties();
 
-            final DbLoader dbLoader = new DbLoader(connection, adapter, new DefaultDbLoaderDelegate()) {
-                @Override
-                public DataMap load(DbLoaderConfiguration config) throws SQLException {
-                    DataMap dataMap = new DataMap();
-                    Map<String, Procedure> procedureMap = loadProcedures(dataMap, config);
-                    load(dataMap, config);
-                    addProcedures(procedureMap);
-                    return dataMap;
-                }
-
-                private void addProcedures(Map<String, Procedure> procedureMap) throws SQLException {
-                    DBElement currentDBCatalog;
-                    DBElement currentDBSchema;
-                    for (Map.Entry<String, Procedure> procedure : procedureMap.entrySet()) {
-                        if (supportCatalogs()) {
-                            String dbCatalogName = procedure.getValue().getCatalog();
-                            DBElement dbCatalog = dbModel.getExistingElement(dbCatalogName);
-                            if (dbCatalog != null) {
-                                currentDBCatalog = dbCatalog;
-                            } else {
-                                currentDBCatalog = new DBCatalog(dbCatalogName);
-                                dbModel.addElement(currentDBCatalog);
-                            }
-                            if (supportSchemas()) {
-                                String dbSchemaName = procedure.getValue().getSchema();
-                                DBElement dbSchema = currentDBCatalog.getExistingElement(dbSchemaName);
-                                if (dbSchema != null) {
-                                    currentDBSchema = dbSchema;
-                                } else {
-                                    currentDBSchema = new DBSchema(dbSchemaName);
-                                    currentDBCatalog.addElement(currentDBSchema);
-                                }
-                                DBProcedure currentProcedure = new DBProcedure(procedure.getValue().getName());
-                                currentDBSchema.addElement(currentProcedure);
-                            } else {
-                                DBProcedure currentProcedure = new DBProcedure(procedure.getValue().getName());
-                                currentDBCatalog.addElement(currentProcedure);
-                            }
-                        } else if (supportSchemas()) {
-                            String dbSchemaName = procedure.getValue().getSchema();
-                            DBElement dbSchema = dbModel.getExistingElement(dbSchemaName);
-                            if (dbSchema != null) {
-                                currentDBSchema = dbSchema;
-                            } else {
-                                currentDBSchema = new DBSchema(dbSchemaName);
-                                dbModel.addElement(currentDBSchema);
-                            }
-                            DBProcedure currentProcedure = new DBProcedure(procedure.getValue().getName());
-                            currentDBSchema.addElement(currentProcedure);
-                        }
-                    }
-                }
-
-                private void createIfNotNull(DataMap dataMap, DbLoaderConfiguration config, 
-                                             String[] types) throws SQLException {
-                    treeEditor.setRoot(dataSourceKey);
-                    dbModel = new DBModel(dataSourceKey);
-                    boolean catalogSetted = false;
-                    DBElement currentDBCatalog = null;
-                    DBElement currentDBSchema = null;
-
-                    for (CatalogFilter catalog : config.getFiltersConfig().catalogs) {
-                        for (SchemaFilter schema : catalog.schemas) {
-                            List<DbEntity> entityList = 
-                                    createTableLoader(catalog.name, schema.name, schema.tables)
-                                            .loadDbEntities(dataMap, config, types);
-                            DbEntity entityFromLoader = entityList.get(0);
-
-                            if (entityFromLoader != null) {
-                                if (!catalogSetted && entityFromLoader.getCatalog() != null) {
-                                    currentDBCatalog = new DBCatalog(entityFromLoader.getCatalog());
-                                    dbModel.addElement(currentDBCatalog);
-                                    catalogSetted = true;
-                                }
-
-                                if (entityFromLoader.getSchema() != null) {
-                                    currentDBSchema = new DBSchema(entityFromLoader.getSchema());
-                                    if (currentDBCatalog != null) {
-                                        currentDBCatalog.addElement(currentDBSchema);
-                                    } else {
-                                        dbModel.addElement(currentDBSchema);
-                                    }
-                                }
-                            }
-
-                            DBEntity currentDBEntity;
-                            if (currentDBSchema != null) {
-                                for (DbEntity dbEntity : entityList) {
-                                    currentDBEntity = new DBEntity(dbEntity.getName());
-                                    currentDBSchema.addElement(currentDBEntity);
-                                    for (DbAttribute dbColumn : dbEntity.getAttributes()) {
-                                        currentDBEntity.addElement(new DBColumn(dbColumn.getName()));
-                                    }
-                                }
-                            } else {
-                                for (DbEntity dbEntity : entityList) {
-                                    currentDBEntity = new DBEntity(dbEntity.getName());
-                                    for (DbAttribute dbColumn : dbEntity.getAttributes()) {
-                                        currentDBEntity.addElement(new DBColumn(dbColumn.getName()));
-                                    }
-                                    currentDBCatalog.addElement(currentDBEntity);
-                                }
-                            }
-                            currentDBSchema = null;
-                        }
-                        catalogSetted = false;
-                        currentDBCatalog = null;
-                    }
-                }
-
-                private void createIfNull(DataMap dataMap, DbLoaderConfiguration config, 
-                                          String[] types) throws SQLException {
-                    
-                    treeEditor.setRoot(dataSourceKey);
-                    dbModel = new DBModel(dataSourceKey);
-                    DBElement currentDBCatalog;
-                    DBElement currentDBSchema;
-
-                    for (CatalogFilter catalog : config.getFiltersConfig().catalogs) {
-                        for (SchemaFilter schema : catalog.schemas) {
-                            List<DbEntity> entityList = 
-                                    createTableLoader(catalog.name, schema.name, schema.tables)
-                                            .loadDbEntities(dataMap, config, types);
-
-                            for (DbEntity dbEntity : entityList) {
-                                if (supportCatalogs()) {
-                                    String dbCatalogName = dbEntity.getCatalog();
-                                    DBElement dbCatalog = dbModel.getExistingElement(dbCatalogName);
-                                    if (dbCatalog != null) {
-                                        currentDBCatalog = dbCatalog;
-                                    } else {
-                                        currentDBCatalog = new DBCatalog(dbCatalogName);
-                                        dbModel.addElement(currentDBCatalog);
-                                    }
-                                    if (supportSchemas()) {
-                                        String dbSchemaName = dbEntity.getSchema();
-                                        DBElement dbSchema = currentDBCatalog.getExistingElement(dbSchemaName);
-                                        if (dbSchema != null) {
-                                            currentDBSchema = dbSchema;
-                                        } else {
-                                            currentDBSchema = new DBSchema(dbSchemaName);
-                                            currentDBCatalog.addElement(currentDBSchema);
-                                        }
-                                        DBEntity currentDBEntity = new DBEntity(dbEntity.getName());
-                                        currentDBSchema.addElement(currentDBEntity);
-                                        for (DbAttribute dbColumn : dbEntity.getAttributes()) {
-                                            currentDBEntity.addElement(new DBColumn(dbColumn.getName()));
-                                        }
-                                    } else {
-                                        DBEntity currentDBEntity = new DBEntity(dbEntity.getName());
-                                        currentDBCatalog.addElement(currentDBEntity);
-                                        for (DbAttribute dbColumn : dbEntity.getAttributes()) {
-                                            currentDBEntity.addElement(new DBColumn(dbColumn.getName()));
-                                        }
-                                    }
-                                } else {
-                                    if (supportSchemas()) {
-                                        String dbSchemaName = dbEntity.getSchema();
-                                        DBElement dbSchema = dbModel.getExistingElement(dbSchemaName);
-                                        if (dbSchema != null) {
-                                            currentDBSchema = dbSchema;
-                                        } else {
-                                            currentDBSchema = new DBSchema(dbSchemaName);
-                                            dbModel.addElement(currentDBSchema);
-                                        }
-                                        DBEntity currentDBEntity = new DBEntity(dbEntity.getName());
-                                        currentDBSchema.addElement(currentDBEntity);
-                                        for (DbAttribute dbColumn : dbEntity.getAttributes()) {
-                                            currentDBEntity.addElement(new DBColumn(dbColumn.getName()));
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-
-                public void load(DataMap dataMap, DbLoaderConfiguration config
-                )
-                        throws SQLException {
-                    LOGGER.info("Schema loading...");
-
-                    String[] types = config.getTableTypes();
-                    if (types == null || types.length == 0) {
-                        types = getDefaultTableTypes();
-                    }
-                    boolean isNullDetected = false;
-                    for (CatalogFilter catalog : config.getFiltersConfig().catalogs) {
-                        for (SchemaFilter schema : catalog.schemas) {
-                            if (schema.name == null && catalog.name == null) {
-                                isNullDetected = true;
-                            }
-                        }
-                    }
-                    if (isNullDetected) {
-                        createIfNull(dataMap, config, types);
-                    } else {
-                        createIfNotNull(dataMap, config, types);
-                    }
-                }
-            };
-
             ReverseEngineering reverseEngineering = xmlFileEditor.convertTextIntoReverseEngineering();
 
             FiltersConfigBuilder filtersConfigBuilder = new FiltersConfigBuilder(reverseEngineering);
             DbLoaderConfiguration dbLoaderConfiguration = new DbLoaderConfiguration();
             dbLoaderConfiguration.setFiltersConfig(filtersConfigBuilder.filtersConfig());
 
-            dbLoader.load(dbLoaderConfiguration);
+            try(Connection connection = dataSource.getConnection()) {
+                DbLoader dbLoader = new ModelerDbLoader(this, treeEditor, connection);
+                dbLoader.load(dbLoaderConfiguration);
+            }
 
             String mapName = projectController.getCurrentDataMap().getName();
 
@@ -342,17 +132,22 @@ public class ReverseEngineeringController extends CayenneController {
         try {
             buildDBProperties();
 
-            ReverseEngineering reverseEngineering = xmlFileEditor.convertTextIntoReverseEngineering();
+            final ReverseEngineering reverseEngineering = xmlFileEditor.convertTextIntoReverseEngineering();
 
-            final DbLoaderHelper helper = new DbLoaderHelper(
-                    projectController,
-                    connection,
-                    adapter,
-                    connectionInfo, reverseEngineering);
             Thread th = new Thread(new Runnable() {
 
                 public void run() {
-                    helper.execute();
+
+                    try(Connection connection = dataSource.getConnection()) {
+                        new DbLoaderHelper(
+                                projectController,
+                                connection,
+                                adapter,
+                                connectionInfo, reverseEngineering).execute();
+                    }
+                    catch (SQLException e) {
+                        LOGGER.warn("Error on execute", e);
+                    }
 
                     SwingUtilities.invokeLater(new Runnable() {
 
@@ -371,13 +166,6 @@ public class ReverseEngineeringController extends CayenneController {
     }
 
     /**
-     * Returns configured DB connection.
-     */
-    public Connection getConnection() {
-        return connection;
-    }
-
-    /**
      * Returns configured DbAdapter.
      */
     public DbAdapter getAdapter() {
@@ -448,4 +236,5 @@ public class ReverseEngineeringController extends CayenneController {
             dataSourceBinding.updateView();
         }
     }
+
 }