This is an automated email from the ASF dual-hosted git repository.

abulatski pushed a commit to branch STABLE-4.1
in repository https://gitbox.apache.org/repos/asf/cayenne.git


The following commit(s) were added to refs/heads/STABLE-4.1 by this push:
     new 8d5a9fe  CAY-2600 Modeler DbImport: Can't retrieve schema for 
databases with no catalog support
8d5a9fe is described below

commit 8d5a9fe1f0b228cd7668c3599c5aa73ad28fa252
Author: Arseni Bulatski <ancars...@gmail.com>
AuthorDate: Fri Aug 23 16:18:05 2019 +0300

    CAY-2600 Modeler DbImport: Can't retrieve schema for databases with no 
catalog support
    
    (cherry picked from commit dc088800eab47bd6b8a34144ef051d6f8c155879)
---
 .../java/org/apache/cayenne/dba/AutoAdapter.java   |  28 +++-
 .../java/org/apache/cayenne/dba/DbAdapter.java     |  23 ++-
 .../java/org/apache/cayenne/dba/JdbcAdapter.java   |  12 +-
 .../org/apache/cayenne/dba/mysql/MySQLAdapter.java |  13 +-
 .../apache/cayenne/dba/oracle/OracleAdapter.java   |  36 +++--
 .../cayenne/dba/sqlserver/SQLServerAdapter.java    |  18 ++-
 .../cayenne/modeler/action/LoadDbSchemaAction.java |   3 +-
 .../editor/dbimport/DatabaseSchemaLoader.java      | 168 +++++++++++----------
 .../modeler/editor/dbimport/DbImportTree.java      |  64 +++++---
 9 files changed, 231 insertions(+), 134 deletions(-)

diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
index 44f1b25..77ef360 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
@@ -7,7 +7,7 @@
  *  "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
+ *    https://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
@@ -19,6 +19,12 @@
 
 package org.apache.cayenne.dba;
 
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.access.translator.ParameterBinding;
@@ -37,15 +43,11 @@ import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.SQLAction;
 import org.apache.cayenne.query.SelectQuery;
 
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.Collection;
-
 /**
  * A DbAdapter that automatically detects the kind of database it is running on
  * and instantiates an appropriate DB-specific adapter, delegating all
  * subsequent method calls to this adapter.
- * 
+ *
  * @since 1.2
  */
 public class AutoAdapter implements DbAdapter {
@@ -62,7 +64,7 @@ public class AutoAdapter implements DbAdapter {
        /**
         * Creates an {@link AutoAdapter} based on a delegate adapter obtained 
via
         * "adapterProvider".
-        * 
+        *
         * @since 3.1
         */
        public AutoAdapter(Provider<DbAdapter> adapterProvider, JdbcEventLogger 
logger) {
@@ -96,7 +98,7 @@ public class AutoAdapter implements DbAdapter {
        protected DbAdapter loadAdapter() {
                return adapterProvider.get();
        }
-       
+
        /**
         * @since 4.0
         */
@@ -242,4 +244,14 @@ public class AutoAdapter implements DbAdapter {
        public EJBQLTranslatorFactory getEjbqlTranslatorFactory() {
                return getAdapter().getEjbqlTranslatorFactory();
        }
+
+       @Override
+       public List<String> getSystemCatalogs() {
+               return Collections.emptyList();
+       }
+
+       @Override
+       public List<String> getSystemSchemas() {
+               return Collections.emptyList();
+       }
 }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
index ae8073e..3d7988f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
  * <p/>
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -18,6 +18,11 @@
  ****************************************************************/
 package org.apache.cayenne.dba;
 
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.List;
+
 import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.access.translator.ParameterBinding;
 import org.apache.cayenne.access.translator.ejbql.EJBQLTranslatorFactory;
@@ -33,10 +38,6 @@ import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.SQLAction;
 import org.apache.cayenne.query.SelectQuery;
 
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.Collection;
-
 /**
  * A Cayenne extension point that abstracts the differences between specifics 
of
  * JDBC interfaces to various databases. Cayenne already ships with a number of
@@ -221,4 +222,16 @@ public interface DbAdapter {
         * @since 4.0
         */
        EJBQLTranslatorFactory getEjbqlTranslatorFactory();
+
+       /**
+        * @since 4.1
+        * @return list of system catalogs
+        */
+       List<String> getSystemCatalogs();
+
+       /**
+        * @since 4.1
+        * @return list of system schemas
+        */
+       List<String> getSystemSchemas();
 }
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
index 4db2b38..1f4493b 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
@@ -7,7 +7,7 @@
  *    "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
+ *      https://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
@@ -592,6 +592,16 @@ public class JdbcAdapter implements DbAdapter {
         return ejbqlTranslatorFactory;
     }
 
+    @Override
+    public List<String> getSystemCatalogs() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public List<String> getSystemSchemas() {
+        return Collections.emptyList();
+    }
+
     /**
      * Sets a translator factory for EJBQL to SQL translation. This property is
      * normally initialized in constructor by calling
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
index b50fbc0..b7adc4e 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
@@ -7,7 +7,7 @@
  *  "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
+ *    https://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
@@ -88,6 +88,8 @@ public class MySQLAdapter extends JdbcAdapter {
 
        protected String storageEngine;
 
+       private String[] SYSTEM_CATALOGS = new String[]{"sys"};
+
        public MySQLAdapter(@Inject RuntimeProperties runtimeProperties,
                                                
@Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> 
defaultExtendedTypes,
                                                
@Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
@@ -123,7 +125,7 @@ public class MySQLAdapter extends JdbcAdapter {
 
        /**
         * Uses special action builder to create the right action.
-        * 
+        *
         * @since 1.2
         */
        @Override
@@ -271,7 +273,7 @@ public class MySQLAdapter extends JdbcAdapter {
         * Customizes PK clause semantics to ensure that generated columns are 
in
         * the beginning of the PK definition, as this seems to be a 
requirement for
         * InnoDB tables.
-        * 
+        *
         * @since 1.2
         */
        // See CAY-358 for details of the InnoDB problem
@@ -363,6 +365,11 @@ public class MySQLAdapter extends JdbcAdapter {
                }
        }
 
+       @Override
+       public List<String> getSystemCatalogs() {
+               return Arrays.asList(SYSTEM_CATALOGS);
+       }
+
        final class PKComparator implements Comparator<DbAttribute> {
 
                public int compare(DbAttribute a1, DbAttribute a2) {
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java
index 77f2be1..827d534 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java
@@ -7,7 +7,7 @@
  *  "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
+ *    https://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
@@ -19,6 +19,17 @@
 
 package org.apache.cayenne.dba.oracle;
 
+import java.lang.reflect.Field;
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.access.translator.ParameterBinding;
@@ -48,16 +59,6 @@ import org.apache.cayenne.query.SelectQuery;
 import org.apache.cayenne.query.UpdateBatchQuery;
 import org.apache.cayenne.resource.ResourceLocator;
 
-import java.lang.reflect.Field;
-import java.sql.CallableStatement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
 /**
  * DbAdapter implementation for <a href="http://www.oracle.com";>Oracle RDBMS
  * </a>. Sample connection settings to use with Oracle are shown below:
@@ -85,6 +86,14 @@ public class OracleAdapter extends JdbcAdapter {
 
        protected static boolean supportsOracleLOB;
 
+       private String[] SYSTEM_SCHEMAS = new String[]{
+                       "ANONYMOUS", "APPQOSSYS", "AUDSYS", "CTXSYS", 
"DBSFWUSER",
+                       "DBSNMP", "DIP", "DVF", "GGSYS", "DVSYS", 
"GSMADMIN_INTERNAL",
+                       "GSMCATUSER", "GSMUSER", "LBACSYS", "MDDATA", "MDSYS", 
"OJVMSYS",
+                       "OLAPSYS", "ORACLE_OCM", "ORDDATA", "ORDPLUGINS", 
"ORDSYS", "OUTLN",
+                       "REMOTE_SCHEDULER_AGENT", "SYSTEM", "WMSYS", 
"SI_INFORMTN_SCHEMA",
+                       "SYS", "SYSBACKUP", "SYSDG", "SYSKM", "SYSRAC", 
"SYS$UMF", "XDB", "XS$NULL"};
+
        static {
                // TODO: as CAY-234 shows, having such initialization done in a 
static
                // fashion
@@ -300,6 +309,11 @@ public class OracleAdapter extends JdbcAdapter {
                return query.createSQLAction(new OracleActionBuilder(node));
        }
 
+       @Override
+       public List<String> getSystemSchemas() {
+               return Arrays.asList(SYSTEM_SCHEMAS);
+       }
+
        /**
         * @since 3.0
         */
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
index a94bf62..3119ee2 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java
@@ -7,7 +7,7 @@
  *  "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
+ *    https://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
@@ -19,6 +19,7 @@
 
 package org.apache.cayenne.dba.sqlserver;
 
+import java.util.Arrays;
 import java.util.List;
 
 import org.apache.cayenne.access.DataNode;
@@ -46,7 +47,7 @@ import org.apache.cayenne.resource.ResourceLocator;
  * <h3>Microsoft Driver Settings</h3>
  * <p>
  * Sample connection settings to use with MS SQL Server are shown below:
- * 
+ *
  * <pre>
  *       sqlserver.jdbc.username = test
  *       sqlserver.jdbc.password = secret
@@ -65,20 +66,22 @@ import org.apache.cayenne.resource.ResourceLocator;
  * "http://jtds.sourceforge.net";>http://jtds.sourceforge.net </a>. It supports
  * both SQLServer and Sybase. Sample SQLServer settings are the following:
  * </p>
- * 
+ *
  * <pre>
  *       sqlserver.jdbc.username = test
  *       sqlserver.jdbc.password = secret
  *       sqlserver.jdbc.url = jdbc:jtds:sqlserver://192.168.0.65/cayenne
  *       sqlserver.jdbc.driver = net.sourceforge.jtds.jdbc.Driver
  * </pre>
- * 
+ *
  * @since 1.1
  */
 public class SQLServerAdapter extends SybaseAdapter {
 
        public static final String TRIM_FUNCTION = "RTRIM";
 
+       private String[] SYSTEM_SCHEMAS = new String[]{"dbo", "sys", 
"INFORMATION_SCHEMA"};
+
        public SQLServerAdapter(@Inject RuntimeProperties runtimeProperties,
                                                        
@Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> 
defaultExtendedTypes,
                                                        
@Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
@@ -100,7 +103,7 @@ public class SQLServerAdapter extends SybaseAdapter {
 
        /**
         * Uses SQLServerActionBuilder to create the right action.
-        * 
+        *
         * @since 1.2
         */
        @Override
@@ -118,4 +121,9 @@ public class SQLServerAdapter extends SybaseAdapter {
                translator.setCaseInsensitive(caseInsensitiveCollations);
                return translator;
        }
+       @Override
+       public List<String> getSystemSchemas() {
+               return Arrays.asList(SYSTEM_SCHEMAS);
+       }
+
 }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/LoadDbSchemaAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/LoadDbSchemaAction.java
index 5958812..f055a91 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/LoadDbSchemaAction.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/LoadDbSchemaAction.java
@@ -22,7 +22,6 @@ package org.apache.cayenne.modeler.action;
 import javax.swing.JOptionPane;
 import javax.swing.tree.TreePath;
 import java.awt.event.ActionEvent;
-import java.sql.SQLException;
 
 import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
 import org.apache.cayenne.modeler.Application;
@@ -104,7 +103,7 @@ public class LoadDbSchemaAction extends CayenneAction {
                 }
 
 
-            } catch (SQLException exception) {
+            } catch (Exception exception) {
                 JOptionPane.showMessageDialog(
                         Application.getFrame(),
                         exception.getMessage(),
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DatabaseSchemaLoader.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DatabaseSchemaLoader.java
index 720541c..fafd9c8 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DatabaseSchemaLoader.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DatabaseSchemaLoader.java
@@ -21,10 +21,13 @@ package org.apache.cayenne.modeler.editor.dbimport;
 
 import javax.swing.tree.TreePath;
 import java.sql.Connection;
+import java.sql.DatabaseMetaData;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Collection;
+import java.util.List;
 
+import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dbsync.reverse.dbimport.Catalog;
 import org.apache.cayenne.dbsync.reverse.dbimport.FilterContainer;
 import org.apache.cayenne.dbsync.reverse.dbimport.IncludeColumn;
@@ -39,9 +42,6 @@ import org.apache.cayenne.modeler.pref.DBConnectionInfo;
 public class DatabaseSchemaLoader {
 
     private static final String INCLUDE_ALL_PATTERN = "%";
-    private static final int TABLE_INDEX = 3;
-    private static final int SCHEMA_INDEX = 2;
-    private static final int CATALOG_INDEX = 1;
 
     private ReverseEngineering databaseReverseEngineering;
 
@@ -51,94 +51,84 @@ public class DatabaseSchemaLoader {
 
     public ReverseEngineering load(DBConnectionInfo connectionInfo,
                                    ClassLoadingService loadingService,
-                                   String[] tableTypesFromConfig) throws 
SQLException {
+                                   String[] tableTypesFromConfig) throws 
Exception {
+        DbAdapter dbAdapter = connectionInfo.makeAdapter(loadingService);
         try (Connection connection = 
connectionInfo.makeDataSource(loadingService).getConnection()) {
             String[] types = tableTypesFromConfig != null && 
tableTypesFromConfig.length != 0 ?
                     tableTypesFromConfig :
                     new String[]{"TABLE", "VIEW", "SYSTEM TABLE",
                             "GLOBAL TEMPORARY", "LOCAL TEMPORARY", "ALIAS", 
"SYNONYM"};
-            processCatalogs(connection, types);
+            processCatalogs(connection, types, dbAdapter);
         }
         return databaseReverseEngineering;
     }
 
-    private void processCatalogs(Connection connection, String[] types) throws 
SQLException {
-        String defaultCatalog = connection.getCatalog();
+    private void processCatalogs(Connection connection, String[] types, 
DbAdapter dbAdapter) throws SQLException {
         try (ResultSet rsCatalog = connection.getMetaData().getCatalogs()) {
             boolean hasCatalogs = false;
+            List<String> systemCatalogs = dbAdapter.getSystemCatalogs();
             while (rsCatalog.next()) {
                 hasCatalogs = true;
-                ResultSet resultSet = connection.getMetaData()
-                        .getTables(processFilter(rsCatalog, defaultCatalog, 
CATALOG_INDEX),
-                                null,
-                                INCLUDE_ALL_PATTERN,
-                                types);
-                packTable(resultSet);
-                packFunctions(connection);
+                String catalog = rsCatalog.getString("TABLE_CAT");
+                if(!systemCatalogs.contains(catalog)) {
+                    processSchemas(connection, types, catalog, dbAdapter);
+                }
             }
             if(!hasCatalogs) {
-                processSchemas(connection, types);
+                processSchemas(connection, types, null, dbAdapter);
             }
         }
     }
 
-    private void processSchemas(Connection connection, String[] types) throws 
SQLException {
-        String defaultSchema = connection.getSchema();
-        try(ResultSet rsSchema = connection.getMetaData().getSchemas()) {
+    private void processSchemas(Connection connection,
+                                String[] types,
+                                String catalog,
+                                DbAdapter dbAdapter) throws SQLException {
+        DatabaseMetaData metaData = connection.getMetaData();
+        try(ResultSet rsSchema = metaData.getSchemas(catalog, null)) {
             boolean hasSchemas = false;
+            List<String> systemSchemas = dbAdapter.getSystemSchemas();
             while (rsSchema.next()) {
                 hasSchemas = true;
-                ResultSet resultSet = connection.getMetaData()
-                        .getTables(null,
-                                processFilter(rsSchema, defaultSchema, 
SCHEMA_INDEX),
-                                INCLUDE_ALL_PATTERN,
-                                types);
-                packTable(resultSet);
-                packFunctions(connection);
+                String schema = rsSchema.getString("TABLE_SCHEM");
+                if(!systemSchemas.contains(schema)) {
+                    ResultSet resultSet = metaData.getTables(catalog, schema, 
INCLUDE_ALL_PATTERN, types);
+                    packTable(resultSet);
+                    packProcedures(connection);
+                }
             }
             if(!hasSchemas) {
-                ResultSet resultSet = connection.getMetaData()
-                        .getTables(null,
-                                null,
-                                INCLUDE_ALL_PATTERN,
-                                types);
-                packTable(resultSet);
+                ResultSet resultSet = metaData.getTables(catalog, null, 
INCLUDE_ALL_PATTERN, types);
                 packTable(resultSet);
+                packProcedures(connection);
             }
         }
     }
 
-    private void packTable(ResultSet resultSet) throws SQLException {
-        while (resultSet.next()) {
-            String tableName = resultSet.getString(TABLE_INDEX);
-            String schemaName = resultSet.getString(SCHEMA_INDEX);
-            String catalogName = resultSet.getString(CATALOG_INDEX);
-            packTable(tableName, catalogName, schemaName, null);
-        }
-    }
-
-    private String processFilter(ResultSet resultSet, String defaultFilter, 
int filterIndex) throws SQLException {
-        return defaultFilter.isEmpty() ?
-                resultSet.getString(filterIndex) :
-                defaultFilter;
-    }
-
     public ReverseEngineering loadColumns(DBConnectionInfo connectionInfo,
                                           ClassLoadingService loadingService,
                                           TreePath path) throws SQLException {
-        Object userObject = 
((DbImportTreeNode)path.getPathComponent(1)).getUserObject();
+        int pathIndex = 1;
         String catalogName = null, schemaName = null;
+
+        Object userObject = getUserObject(path, pathIndex);
         if(userObject instanceof Catalog) {
             catalogName = ((Catalog) userObject).getName();
+            userObject = getUserObject(path, ++pathIndex);
+            if(userObject instanceof Schema) {
+                schemaName = ((Schema) userObject).getName();
+                userObject = getUserObject(path, ++pathIndex);
+            }
         } else if(userObject instanceof Schema) {
             schemaName = ((Schema) userObject).getName();
+            userObject = getUserObject(path, ++pathIndex);
         }
-        String tableName = path.getPathComponent(2).toString();
 
+        String tableName = processTable(userObject);
         try (Connection connection = 
connectionInfo.makeDataSource(loadingService).getConnection()) {
             try (ResultSet rs = 
connection.getMetaData().getColumns(catalogName, schemaName, tableName, null)) {
                 while (rs.next()) {
-                    String column = rs.getString(4);
+                    String column = rs.getString("COLUMN_NAME");
                     packTable(tableName, catalogName, schemaName, column);
                 }
             }
@@ -146,45 +136,62 @@ public class DatabaseSchemaLoader {
         return databaseReverseEngineering;
     }
 
-    private void packFunctions(Connection connection) throws SQLException {
+    private Object getUserObject(TreePath path, int pathIndex) {
+        return 
((DbImportTreeNode)path.getPathComponent(pathIndex)).getUserObject();
+    }
+
+    private String processTable(Object userObject) {
+        if(userObject instanceof IncludeTable) {
+            return  ((IncludeTable) userObject).getPattern();
+        }
+        return null;
+    }
+
+    private void packProcedures(Connection connection) throws SQLException {
         Collection<Catalog> catalogs = 
databaseReverseEngineering.getCatalogs();
-        for (Catalog catalog : catalogs) {
-            ResultSet procResultSet = connection.getMetaData().getProcedures(
-                    catalog.getName(), null, "%"
-            );
-            while (procResultSet.next()) {
-                IncludeProcedure includeProcedure = new 
IncludeProcedure(procResultSet.getString(3));
-                if 
(!catalog.getIncludeProcedures().contains(includeProcedure)) {
-                    catalog.addIncludeProcedure(includeProcedure);
+        for(Catalog catalog : catalogs) {
+            Collection<Schema> schemas = catalog.getSchemas();
+            if(!schemas.isEmpty()) {
+                for(Schema schema : schemas) {
+                    ResultSet procResultSet = getProcedures(connection, 
catalog.getName(), schema.getName());
+                    packFunction(procResultSet, schema);
                 }
+            } else {
+                ResultSet procResultSet = getProcedures(connection, 
catalog.getName(), null);
+                packFunction(procResultSet, catalog);
             }
         }
-        for (Schema schema : databaseReverseEngineering.getSchemas()) {
-            ResultSet procResultSet = connection.getMetaData().getProcedures(
-                    null, schema.getName(), "%"
-            );
-            while (procResultSet.next()) {
-                IncludeProcedure includeProcedure = new 
IncludeProcedure(procResultSet.getString(3));
-                if (!schema.getIncludeProcedures().contains(includeProcedure)) 
{
-                    schema.addIncludeProcedure(includeProcedure);
-                }
-            }
+
+        Collection<Schema> schemas = databaseReverseEngineering.getSchemas();
+        for(Schema schema : schemas) {
+            ResultSet procResultSet = getProcedures(connection, null, 
schema.getName());
+            packFunction(procResultSet, schema);
         }
-        for (Catalog catalog : catalogs) {
-            for (Schema schema : catalog.getSchemas()) {
-                ResultSet procResultSet = 
connection.getMetaData().getProcedures(
-                        catalog.getName(), schema.getName(), "%"
-                );
-                while (procResultSet.next()) {
-                    IncludeProcedure includeProcedure = new 
IncludeProcedure(procResultSet.getString(3));
-                    if 
(!schema.getIncludeProcedures().contains(includeProcedure)) {
-                        schema.addIncludeProcedure(includeProcedure);
-                    }
-                }
+    }
+
+    private ResultSet getProcedures(Connection connection, String catalog, 
String schema) throws SQLException {
+        return connection.getMetaData().getProcedures(catalog, schema, "%");
+    }
+
+    private void packFunction(ResultSet resultSet, FilterContainer 
filterContainer) throws SQLException {
+        while (resultSet.next()) {
+            IncludeProcedure includeProcedure =
+                    new 
IncludeProcedure(resultSet.getString("PROCEDURE_NAME"));
+            if 
(!filterContainer.getIncludeProcedures().contains(includeProcedure)) {
+                filterContainer.addIncludeProcedure(includeProcedure);
             }
         }
     }
 
+    private void packTable(ResultSet resultSet) throws SQLException {
+        while (resultSet.next()) {
+            String tableName = resultSet.getString("TABLE_NAME");
+            String schemaName = resultSet.getString("TABLE_SCHEM");
+            String catalogName = resultSet.getString("TABLE_CAT");
+            packTable(tableName, catalogName, schemaName, null);
+        }
+    }
+
     private void packTable(String tableName, String catalogName, String 
schemaName, String columnName) {
         IncludeTable table = new IncludeTable();
         table.setPattern(tableName);
@@ -230,6 +237,7 @@ public class DatabaseSchemaLoader {
                 parentCatalog.setName(catalogName);
                 parentSchema = new Schema();
                 parentSchema.setName(schemaName);
+                parentCatalog.addSchema(parentSchema);
                 databaseReverseEngineering.addCatalog(parentCatalog);
             }
             filterContainer = parentSchema;
@@ -248,7 +256,7 @@ public class DatabaseSchemaLoader {
     private void addColumn(FilterContainer filterContainer, IncludeTable 
table, String columnName) {
         IncludeTable foundTable = 
getTableByName(filterContainer.getIncludeTables(), table.getPattern());
         table = foundTable != null ? foundTable : table;
-        if (columnName != null ) {
+        if (columnName != null) {
             IncludeColumn includeColumn = new IncludeColumn(columnName);
             table.addIncludeColumn(includeColumn);
         }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportTree.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportTree.java
index fdc497b..08ec582 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportTree.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportTree.java
@@ -75,35 +75,61 @@ public class DbImportTree extends JTree {
 
     public void updateTableColumns(ReverseEngineering reverseEngineering) {
         DbImportModel model = (DbImportModel) this.getModel();
-
         DbImportTreeNode root = (DbImportTreeNode) model.getRoot();
         Collection<Catalog> catalogs = reverseEngineering.getCatalogs();
-        Collection<? extends FilterContainer> filterContainers = 
!catalogs.isEmpty() ?
-                catalogs :
-                reverseEngineering.getSchemas();
-        filterContainers.forEach(filterContainer -> {
-            DbImportTreeNode container = findNodeInParent(root, 
filterContainer);
+        if(!catalogs.isEmpty()) {
+            catalogs.forEach(catalog -> {
+                Collection<Schema> schemas = catalog.getSchemas();
+                if(!schemas.isEmpty()) {
+                    DbImportTreeNode currentRoot = findNodeInParent(root, 
catalog);
+                    schemas.forEach(schema -> packNextFilter(schema, 
currentRoot, model));
+                } else {
+                    packNextFilter(catalog, root, model);
+                }
+            });
+        } else {
+            reverseEngineering.getSchemas().forEach(schema -> {
+                packNextFilter(schema, root, model);
+            });
+        }
+    }
+
+    private void packNextFilter(FilterContainer filterContainer,
+                                DbImportTreeNode root,
+                                DbImportModel model) {
+        DbImportTreeNode container = findNodeInParent(root, filterContainer);
 
+        if (container == null) {
+            return;
+        }
+
+        packTables(filterContainer, container, model);
+    }
+
+    private void packTables(FilterContainer filterContainer,
+                            DbImportTreeNode root,
+                            DbImportModel model) {
+        filterContainer.getIncludeTables().forEach(tableFilter -> {
+            DbImportTreeNode container = findNodeInParent(root, tableFilter );
             if (container == null) {
                 return;
             }
+            if (container.getChildCount() != 0) {
+                container.removeAllChildren();
+            }
 
-            filterContainer.getIncludeTables().forEach(newTable -> {
-                DbImportTreeNode table = findNodeInParent(container, newTable);
-                if (table == null) {
-                    return;
-                }
-                if (table.getChildCount() != 0) {
-                    table.removeAllChildren();
-                }
-                newTable.getIncludeColumns().forEach(column ->
-                        table.add(new DbImportTreeNode(column)));
-                table.setLoaded(true);
-                model.reload(table);
-            });
+            packColumns(tableFilter , container);
+
+            container.setLoaded(true);
+            model.reload(container);
         });
     }
 
+    private void packColumns(IncludeTable includeTable, DbImportTreeNode 
tableNode) {
+        includeTable.getIncludeColumns().forEach(column ->
+                tableNode.add(new DbImportTreeNode(column)));
+    }
+
     private DbImportTreeNode findNodeInParent(DbImportTreeNode parent, Object 
object) {
         for (int i = 0; i < parent.getChildCount(); i++) {
             DbImportTreeNode node = (DbImportTreeNode) parent.getChildAt(i);

Reply via email to