You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by sk...@apache.org on 2016/12/19 11:46:21 UTC

[05/10] cayenne git commit: Unify logic of Merge and ReverseEngineer actions

Unify logic of Merge and ReverseEngineer actions


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

Branch: refs/heads/master
Commit: 190ab7c7b72eb846ed39c7c80e4fa9a51046adf1
Parents: 7da0e89
Author: Nikita Timofeev <st...@gmail.com>
Authored: Wed Dec 14 10:56:59 2016 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Wed Dec 14 10:56:59 2016 +0300

----------------------------------------------------------------------
 .../cayenne/modeler/action/DBWizardAction.java  |  61 +++++-
 .../modeler/action/GenerateDBAction.java        |   3 +-
 .../cayenne/modeler/action/MigrateAction.java   |  50 +----
 .../action/ReverseEngineeringAction.java        |  53 +----
 .../modeler/dialog/DbImportProjectSaver.java    |  77 --------
 .../dialog/db/DbActionOptionsDialog.java        | 175 +++++++++++++++++
 .../dialog/db/load/DbLoaderOptionsDialog.java   | 193 +++----------------
 .../dialog/db/merge/DbMigrateOptionsDialog.java | 155 +--------------
 8 files changed, 283 insertions(+), 484 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/190ab7c7/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DBWizardAction.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DBWizardAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DBWizardAction.java
index a3e652a..4002d58 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DBWizardAction.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DBWizardAction.java
@@ -19,13 +19,20 @@
 
 package org.apache.cayenne.modeler.action;
 
+import java.sql.Connection;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.swing.JOptionPane;
+
+import org.apache.cayenne.dbsync.reverse.db.DbLoader;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.dialog.db.DataSourceWizard;
+import org.apache.cayenne.modeler.dialog.db.DbActionOptionsDialog;
 import org.apache.cayenne.modeler.util.CayenneAction;
 
-/**
- */
-public abstract class DBWizardAction extends CayenneAction {
+public abstract class DBWizardAction<T extends DbActionOptionsDialog> extends CayenneAction {
 
     public DBWizardAction(String name, Application application) {
         super(name, application);
@@ -40,4 +47,52 @@ public abstract class DBWizardAction extends CayenneAction {
 
         return connectWizard;
     }
+
+    protected abstract T createDialog(Collection<String> catalogs, Collection<String> schemas, String currentCatalog, String currentSchema);
+
+    protected T loaderOptionDialog(DataSourceWizard connectWizard) {
+
+        // use this catalog as the default...
+        List<String> catalogs;
+        List<String> schemas;
+        String currentCatalog;
+        String currentSchema;
+        try(Connection connection = connectWizard.getDataSource().getConnection()) {
+            catalogs = getCatalogs(connectWizard, connection);
+            schemas = getSchemas(connection);
+            if (catalogs.isEmpty() && schemas.isEmpty()) {
+                return null;
+            }
+            currentCatalog = connection.getCatalog();
+            currentSchema = connection.getSchema();
+        } catch (Exception ex) {
+            JOptionPane.showMessageDialog(
+                    Application.getFrame(),
+                    ex.getMessage(),
+                    "Error loading schemas dialog",
+                    JOptionPane.ERROR_MESSAGE);
+            return null;
+        }
+
+        final T optionsDialog = createDialog(catalogs, schemas, currentCatalog, currentSchema);
+        optionsDialog.setVisible(true);
+        if (optionsDialog.getChoice() == DbActionOptionsDialog.SELECT) {
+            return optionsDialog;
+        }
+
+        return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    private List<String> getCatalogs(DataSourceWizard connectWizard, Connection connection) throws Exception {
+        if(!connectWizard.getAdapter().supportsCatalogsOnReverseEngineering()) {
+            return (List<String>) Collections.EMPTY_LIST;
+        }
+
+        return DbLoader.loadCatalogs(connection);
+    }
+
+    private List<String> getSchemas(Connection connection) throws Exception {
+        return DbLoader.loadSchemas(connection);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/190ab7c7/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/GenerateDBAction.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/GenerateDBAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/GenerateDBAction.java
index 1cf6301..93c6409 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/GenerateDBAction.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/GenerateDBAction.java
@@ -23,6 +23,7 @@ import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.dialog.db.gen.DBGeneratorOptions;
+import org.apache.cayenne.modeler.util.CayenneAction;
 import org.apache.cayenne.project.Project;
 
 import java.awt.event.ActionEvent;
@@ -32,7 +33,7 @@ import java.util.Collection;
 /**
  * Action that generates database tables from a DataMap.
  */
-public class GenerateDBAction extends DBWizardAction {
+public class GenerateDBAction extends CayenneAction {
 
     public static String getActionName() {
         return "Generate Database Schema";

http://git-wip-us.apache.org/repos/asf/cayenne/blob/190ab7c7/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java
index 29cd6a7..ccf6d3e 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java
@@ -20,23 +20,19 @@
 package org.apache.cayenne.modeler.action;
 
 import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactoryProvider;
-import org.apache.cayenne.dbsync.reverse.db.DbLoader;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.dialog.db.DataSourceWizard;
 import org.apache.cayenne.modeler.dialog.db.merge.DbMigrateOptionsDialog;
 import org.apache.cayenne.modeler.dialog.db.merge.MergerOptions;
 
-import javax.sql.DataSource;
-import javax.swing.JOptionPane;
 import java.awt.event.ActionEvent;
-import java.util.Collections;
-import java.util.List;
+import java.util.Collection;
 
 /**
  * Action that alter database schema to match a DataMap.
  */
-public class MigrateAction extends DBWizardAction {
+public class MigrateAction extends DBWizardAction<DbMigrateOptionsDialog> {
 
     public MigrateAction(Application application) {
         super(getActionName(), application);
@@ -58,29 +54,9 @@ public class MigrateAction extends DBWizardAction {
             throw new IllegalStateException("No current DataMap selected.");
         }
 
-        //showOptions dialog
-        String selectedSchema = null;
-        String selectedCatalog = null;
-        try {
-            List<String> schemas = getSchemas(connectWizard);
-            List<String> catalogs = getCatalogs(connectWizard);
-            if (!catalogs.isEmpty() || !schemas.isEmpty()) {
-                DbMigrateOptionsDialog optionsDialog = new DbMigrateOptionsDialog(catalogs, schemas, connectWizard.getConnectionInfo().getUserName());
-                optionsDialog.showDialog();
-                if (optionsDialog.getChoice() == DbMigrateOptionsDialog.SELECT) {
-                    selectedSchema = optionsDialog.getSelectedSchema();
-                    selectedCatalog = optionsDialog.getSelectedCatalog();
-                } else {
-                    return;
-                }
-            }
-        } catch (Exception ex) {
-            JOptionPane.showMessageDialog(
-                    Application.getFrame(),
-                    ex.getMessage(),
-                    "Error loading schemas dialog",
-                    JOptionPane.ERROR_MESSAGE);
-        }
+        DbMigrateOptionsDialog optionsDialog = loaderOptionDialog(connectWizard);
+        String selectedCatalog = optionsDialog == null ? null : optionsDialog.getSelectedCatalog();
+        String selectedSchema = optionsDialog == null ? null : optionsDialog.getSelectedSchema();
 
         MergerTokenFactoryProvider mergerTokenFactoryProvider =
                 getApplication().getInjector().getInstance(MergerTokenFactoryProvider.class);
@@ -93,18 +69,8 @@ public class MigrateAction extends DBWizardAction {
                 map, selectedCatalog, selectedSchema, mergerTokenFactoryProvider).startupAction();
     }
 
-    @SuppressWarnings("unchecked")
-    private List<String> getCatalogs(DataSourceWizard connectWizard) throws Exception {
-        if(!connectWizard.getAdapter().supportsCatalogsOnReverseEngineering()) {
-            return (List<String>)Collections.EMPTY_LIST;
-        }
-
-        DataSource dataSource = connectWizard.getDataSource();
-        return DbLoader.loadCatalogs(dataSource.getConnection());
-    }
-
-    private List<String> getSchemas(DataSourceWizard connectWizard) throws Exception {
-        DataSource dataSource = connectWizard.getDataSource();
-        return DbLoader.loadSchemas(dataSource.getConnection());
+    @Override
+    protected DbMigrateOptionsDialog createDialog(Collection<String> catalogs, Collection<String> schemas, String currentCatalog, String currentSchema) {
+        return new DbMigrateOptionsDialog(catalogs, schemas, currentCatalog, currentSchema);
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/190ab7c7/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ReverseEngineeringAction.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ReverseEngineeringAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ReverseEngineeringAction.java
index 8088639..a2fefb7 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ReverseEngineeringAction.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/ReverseEngineeringAction.java
@@ -19,7 +19,6 @@
 
 package org.apache.cayenne.modeler.action;
 
-import org.apache.cayenne.dbsync.reverse.db.DbLoader;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.dialog.db.DataSourceWizard;
 import org.apache.cayenne.modeler.dialog.db.load.DbLoaderContext;
@@ -28,14 +27,13 @@ import org.apache.cayenne.modeler.dialog.db.load.LoadDataMapTask;
 
 import java.awt.event.ActionEvent;
 import java.sql.SQLException;
-import java.util.Collections;
-import java.util.List;
+import java.util.Collection;
 import javax.swing.SwingUtilities;
 
 /**
  * Action that imports database structure into a DataMap.
  */
-public class ReverseEngineeringAction extends DBWizardAction {
+public class ReverseEngineeringAction extends DBWizardAction<DbLoaderOptionsDialog> {
 
     ReverseEngineeringAction(Application application) {
         super(getActionName(), application);
@@ -63,7 +61,7 @@ public class ReverseEngineeringAction extends DBWizardAction {
             return;
         }
 
-        final DbLoaderOptionsDialog loaderOptionsDialog = loaderOptionDialog(connectWizard, context);
+        final DbLoaderOptionsDialog loaderOptionsDialog = loaderOptionDialog(connectWizard);
         if(!context.buildConfig(connectWizard, loaderOptionsDialog)) {
             return;
         }
@@ -92,47 +90,8 @@ public class ReverseEngineeringAction extends DBWizardAction {
         th.start();
     }
 
-    private DbLoaderOptionsDialog loaderOptionDialog(DataSourceWizard connectWizard, DbLoaderContext context) {
-        if(connectWizard == null) {
-            return null;
-        }
-
-        List<String> catalogs = Collections.emptyList();
-        List<String> schemas = Collections.emptyList();
-        try {
-            schemas = DbLoader.loadSchemas(context.getConnection());
-            if (connectWizard.getAdapter().supportsCatalogsOnReverseEngineering()) {
-                catalogs = DbLoader.loadCatalogs(context.getConnection());
-            }
-        } catch (SQLException ex) {
-            context.processWarn(ex, "Error Loading catalogs and schemas");
-        }
-
-        if (context.isStopping()) {
-            return null;
-        }
-
-        // use this catalog as the default...
-        String currentCatalog = null;
-        String currentSchema = null;
-        try {
-            currentCatalog = context.getConnection().getCatalog();
-            currentSchema = context.getConnection().getSchema();
-        } catch (SQLException e) {
-            context.processWarn(e, "Error getting catalog or schema");
-        }
-
-        final DbLoaderOptionsDialog dialog = new DbLoaderOptionsDialog(
-                schemas, catalogs,
-                currentSchema, currentCatalog
-        );
-        dialog.setVisible(true);
-        dialog.dispose();
-
-        if (dialog.getChoice() == DbLoaderOptionsDialog.CANCEL) {
-            return null;
-        }
-
-        return dialog;
+    @Override
+    protected DbLoaderOptionsDialog createDialog(Collection<String> catalogs, Collection<String> schemas, String currentCatalog, String currentSchema) {
+        return new DbLoaderOptionsDialog(catalogs, schemas, currentCatalog, currentSchema);
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/190ab7c7/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/DbImportProjectSaver.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/DbImportProjectSaver.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/DbImportProjectSaver.java
deleted file mode 100644
index a422143..0000000
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/DbImportProjectSaver.java
+++ /dev/null
@@ -1,77 +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.modeler.dialog;
-
-import org.apache.cayenne.configuration.ConfigurationNameMapper;
-import org.apache.cayenne.configuration.DataChannelDescriptor;
-import org.apache.cayenne.configuration.event.DataMapEvent;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.event.MapEvent;
-import org.apache.cayenne.modeler.Application;
-import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.project.Project;
-import org.apache.cayenne.project.ProjectSaver;
-import org.apache.cayenne.resource.Resource;
-
-public class DbImportProjectSaver implements ProjectSaver {
-
-    //@Inject // unfortunate we are not in DI context for now
-    protected ConfigurationNameMapper nameMapper;
-
-    private ProjectController projectController;
-
-    public DbImportProjectSaver(ProjectController projectController, ConfigurationNameMapper nameMapper) {
-        this.projectController = projectController;
-        this.nameMapper = nameMapper;
-    }
-
-    @Override
-    public String getSupportedVersion() {
-        // not important in the context of non-saving saver
-        return "-1";
-    }
-
-    @Override
-    public void save(Project project) {
-
-        DataMap dataMap = (DataMap) project.getRootNode();
-
-        if (projectController.getCurrentDataMap() != null) {
-
-            projectController.fireDataMapEvent(new DataMapEvent(Application.getFrame(), dataMap, MapEvent.REMOVE));
-            projectController.fireDataMapEvent(new DataMapEvent(Application.getFrame(), dataMap, MapEvent.ADD));
-        } else {
-
-            DataChannelDescriptor currentDomain = (DataChannelDescriptor) projectController.getProject().getRootNode();
-            Resource baseResource = currentDomain.getConfigurationSource();
-
-            // a new DataMap, so need to set configuration source for it
-            if (baseResource != null) {
-                Resource dataMapResource = baseResource.getRelativeResource(nameMapper.configurationLocation(dataMap));
-                dataMap.setConfigurationSource(dataMapResource);
-            }
-            projectController.addDataMap(Application.getFrame(), dataMap);
-        }
-    }
-
-    @Override
-    public void saveAs(Project project, Resource baseDirectory) {
-        save(project);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/190ab7c7/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbActionOptionsDialog.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbActionOptionsDialog.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbActionOptionsDialog.java
new file mode 100644
index 0000000..19c479b
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbActionOptionsDialog.java
@@ -0,0 +1,175 @@
+/*****************************************************************
+ *   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 java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.HeadlessException;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Collection;
+
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import com.jgoodies.forms.builder.DefaultFormBuilder;
+import com.jgoodies.forms.layout.FormLayout;
+import org.apache.cayenne.modeler.util.CayenneDialog;
+
+public abstract class DbActionOptionsDialog extends CayenneDialog {
+
+    protected static final String WILDCARD_PATTERN = ".*";
+    public static final int CANCEL = 0;
+    public static final int SELECT = 1;
+
+    private int choice;
+    private JLabel schemaLabel;
+    private JLabel catalogLabel;
+    private JComboBox<String> catalogSelector;
+    private JComboBox<String> schemaSelector;
+    private JButton selectButton;
+    private JButton cancelButton;
+
+    public DbActionOptionsDialog(Frame owner, String title, Collection<String> catalogs, Collection<String> schemas,
+                                 String currentCatalog, String currentSchema) throws HeadlessException {
+        super(owner, title);
+        init();
+        initController();
+        initFromModel(catalogs, schemas, currentCatalog, currentSchema);
+
+        pack();
+        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+        setModal(true);
+        centerWindow();
+    }
+
+    protected void init() {
+        // create widgets...
+        selectButton = new JButton("Continue");
+        cancelButton = new JButton("Cancel");
+        catalogSelector = new JComboBox<>();
+        schemaSelector = new JComboBox<>();
+
+        FormLayout layout = new FormLayout(
+                "right:pref, 3dlu, fill:max(170dlu;pref):grow",
+                "");
+        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
+        builder.setDefaultDialogBorder();
+
+        catalogLabel = builder.append("Select Catalog:", catalogSelector, true);
+        schemaLabel = builder.append("Select Schema:", schemaSelector);
+
+        initForm(builder);
+
+        JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+        buttons.add(selectButton);
+        buttons.add(cancelButton);
+
+        getContentPane().setLayout(new BorderLayout());
+        getContentPane().add(builder.getPanel(), BorderLayout.CENTER);
+        getContentPane().add(buttons, BorderLayout.SOUTH);
+    }
+
+    protected void initController() {
+        selectButton.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                processSelect();
+            }
+        });
+        cancelButton.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                processCancel();
+            }
+        });
+    }
+
+    protected void initFromModel(Collection<String> catalogs, Collection<String> schemas, String currentCatalog, String currentSchema) {
+        this.choice = CANCEL;
+
+        boolean showSchemaSelector = schemas != null && !schemas.isEmpty();
+        schemaSelector.setVisible(showSchemaSelector);
+        schemaLabel.setVisible(showSchemaSelector);
+        if (showSchemaSelector) {
+            schemaSelector.setModel(new DefaultComboBoxModel<>(schemas.toArray(new String[0])));
+            if (currentSchema != null) {
+                for (String schema : schemas) {
+                    if (currentSchema.equalsIgnoreCase(schema)) {
+                        schemaSelector.setSelectedItem(schema);
+                        break;
+                    }
+                }
+            }
+        }
+
+        boolean showCatalogSelector = catalogs != null && !catalogs.isEmpty();
+        catalogSelector.setVisible(showCatalogSelector);
+        catalogLabel.setVisible(showCatalogSelector);
+        if (showCatalogSelector) {
+            catalogSelector.setModel(new DefaultComboBoxModel<>(catalogs.toArray(new String[0])));
+            if (currentCatalog != null && !currentCatalog.isEmpty()) {
+                for (String catalog : catalogs) {
+                    if (currentCatalog.equalsIgnoreCase(catalog)) {
+                        catalogSelector.setSelectedItem(catalog);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    protected abstract void initForm(DefaultFormBuilder builder);
+
+    public int getChoice() {
+        return choice;
+    }
+
+    private void processSelect() {
+        choice = SELECT;
+        setVisible(false);
+    }
+
+    private void processCancel() {
+        choice = CANCEL;
+        setVisible(false);
+    }
+
+    /**
+     * Returns selected catalog.
+     */
+    public String getSelectedCatalog() {
+        String catalog = (String) catalogSelector.getSelectedItem();
+        return "".equals(catalog) ? null : catalog;
+    }
+
+    /**
+     * Returns selected schema.
+     */
+    public String getSelectedSchema() {
+        String schema = (String) schemaSelector.getSelectedItem();
+        return "".equals(schema) ? null : schema;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/190ab7c7/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoaderOptionsDialog.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoaderOptionsDialog.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoaderOptionsDialog.java
index 1ccc7aa..e1c422e 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoaderOptionsDialog.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoaderOptionsDialog.java
@@ -20,127 +20,60 @@
 package org.apache.cayenne.modeler.dialog.db.load;
 
 import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
 import org.apache.cayenne.modeler.Application;
-import org.apache.cayenne.modeler.util.CayenneDialog;
+import org.apache.cayenne.modeler.dialog.db.DbActionOptionsDialog;
 import org.apache.cayenne.modeler.util.NameGeneratorPreferences;
 
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.util.Collection;
 import java.util.Vector;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JComboBox;
+import javax.swing.JTextField;
 
 /**
  * Dialog for selecting database reverse-engineering parameters.
  */
-public class DbLoaderOptionsDialog extends CayenneDialog {
+public class DbLoaderOptionsDialog extends DbActionOptionsDialog {
 
-    public static final String WILDCARD_PATTERN = ".*";
-
-    public static final int CANCEL = 0;
-    public static final int SELECT = 1;
-
-    protected JLabel catalogLabel;
-    protected JComboBox<String> catalogSelector;
-    protected JLabel schemaLabel;
-    protected JComboBox<String> schemaSelector;
-    protected JTextField tableNamePatternField;
-    protected JTextField meaningfulPk;
-    protected JTextField procNamePatternField;
-    protected JLabel procedureLabel;
-    protected JButton selectButton;
-    protected JButton cancelButton;
-
-
-    protected JComboBox<String> strategyCombo;
+    private JTextField tableNamePatternField;
+    private JTextField meaningfulPk;
+    private JTextField procNamePatternField;
+    private JComboBox<String> strategyCombo;
     protected String strategy;
-    protected int choice;
 
     /**
      * Creates and initializes new ChooseSchemaDialog.
      */
-    public DbLoaderOptionsDialog(Collection<String> schemas, Collection<String> catalogs, String currentSchema,
-                                 String dbCatalog) {
-        super(Application.getFrame(), "Reengineer DB Schema: Select Options");
-
-        init();
-        initController();
-        initFromModel(schemas, catalogs, currentSchema, dbCatalog);
-
-        pack();
-        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-        setModal(true);
-        centerWindow();
+    public DbLoaderOptionsDialog(Collection<String> catalogs, Collection<String> schemas,
+                                 String dbCatalog, String currentSchema) {
+        super(Application.getFrame(), "Reengineer DB Schema: Select Options",
+                catalogs, schemas, dbCatalog, currentSchema);
     }
 
-    /** Sets up the graphical components. */
-    protected void init() {
-
-        // create widgets...
-        selectButton = new JButton("Continue");
-        cancelButton = new JButton("Cancel");
-        catalogSelector = new JComboBox<>();
-        schemaSelector = new JComboBox<>();
+    @Override
+    protected void initForm(DefaultFormBuilder builder) {
         tableNamePatternField = new JTextField();
         tableNamePatternField.setToolTipText("<html>Regular expression to filter table names.<br>" +
                 "Default expression <b>.*</b> includes all tables.</html>");
         procNamePatternField = new JTextField();
         procNamePatternField.setToolTipText("<html>Regular expression to filter stored procedures names.<br>" +
-                "Default expression .* includes all stored procedures.</html>");
+                "Default expression <b>.*</b> includes all stored procedures.</html>");
         meaningfulPk = new JTextField();
         meaningfulPk.setToolTipText("<html>Regular expression to filter tables with meaningful primary keys.<br>" +
                 "Multiple expressions divided by comma can be used.<br>" +
-                "Example: <b>^table1,^table2,^prefix.*</b></html>");
+                "Example: <b>^table1|^table2|^prefix.*|table_name</b></html>");
         strategyCombo = new JComboBox<>();
         strategyCombo.setEditable(true);
 
-        // assemble
-        FormLayout layout = new FormLayout(
-                "right:pref, 3dlu, fill:max(170dlu;pref):grow",
-                "");
-        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
-        builder.setDefaultDialogBorder();
-
-        catalogLabel = builder.append("Select Catalog:", catalogSelector);
-        schemaLabel = builder.append("Select Schema:", schemaSelector);
         builder.append("Table Name Pattern:", tableNamePatternField);
-        procedureLabel = builder.append("Procedure Name Pattern:", procNamePatternField);
+        builder.append("Procedure Name Pattern:", procNamePatternField);
         builder.append("Naming Strategy:", strategyCombo);
         builder.append("Tables with Meaningful PK Pattern:", meaningfulPk);
-
-        JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
-        buttons.add(cancelButton);
-        buttons.add(selectButton);
-
-        getContentPane().setLayout(new BorderLayout());
-        getContentPane().add(builder.getPanel(), BorderLayout.CENTER);
-        getContentPane().add(buttons, BorderLayout.SOUTH);
     }
 
-    protected void initController() {
-        selectButton.addActionListener(new ActionListener() {
-
-            public void actionPerformed(ActionEvent e) {
-                processSelect();
-            }
-        });
-        cancelButton.addActionListener(new ActionListener() {
+    protected void initFromModel(Collection<String> catalogs, Collection<String> schemas, String currentCatalog, String currentSchema) {
+        super.initFromModel(catalogs, schemas, currentCatalog, currentSchema);
 
-            public void actionPerformed(ActionEvent e) {
-                processCancel();
-            }
-        });
-    }
-
-    protected void initFromModel(
-            Collection<String> schemas,
-            Collection<String> catalogs,
-            String currentSchema,
-            String currentCatalog) {
-
-        this.choice = CANCEL;
         this.tableNamePatternField.setText(WILDCARD_PATTERN);
         this.procNamePatternField.setText(WILDCARD_PATTERN);
 
@@ -148,100 +81,24 @@ public class DbLoaderOptionsDialog extends CayenneDialog {
                 .getInstance()
                 .getLastUsedStrategies();
         strategyCombo.setModel(new DefaultComboBoxModel<>(arr));
-
-        boolean showSchemaSelector = schemas != null && !schemas.isEmpty();
-        schemaSelector.setVisible(showSchemaSelector);
-        schemaLabel.setVisible(showSchemaSelector);
-
-        if (showSchemaSelector) {
-
-            schemaSelector.setModel(new DefaultComboBoxModel<>(schemas.toArray(new String[0])));
-
-            if (currentSchema != null) {
-                for (String schema : schemas) {
-                    if (currentSchema.equalsIgnoreCase(schema)) {
-                        schemaSelector.setSelectedItem(schema);
-                        break;
-                    }
-                }
-            }
-        }
-
-        boolean showCatalogSelector = catalogs != null && !catalogs.isEmpty();
-        catalogSelector.setVisible(showCatalogSelector);
-        catalogLabel.setVisible(showCatalogSelector);
-
-        if (showCatalogSelector) {
-            catalogSelector.setModel(new DefaultComboBoxModel<>(catalogs.toArray(new String[0])));
-
-            if (currentCatalog != null && !currentCatalog.isEmpty()) {
-                for (String catalog : catalogs) {
-                    if (currentCatalog.equalsIgnoreCase(catalog)) {
-                        catalogSelector.setSelectedItem(catalog);
-                        break;
-                    }
-                }
-            }
-        }
     }
 
-    public int getChoice() {
-        return choice;
-    }
-
-    private void processSelect() {
-        strategy = (String) strategyCombo.getSelectedItem();
-
-        choice = SELECT;
-        setVisible(false);
-    }
-
-    private void processCancel() {
-        choice = CANCEL;
-        setVisible(false);
-    }
-
-    /**
-     * Returns selected catalog.
-     */
-    public String getSelectedCatalog() {
-        String catalog = (String) catalogSelector.getSelectedItem();
-        return "".equals(catalog) ? null : catalog;
-    }
-
-    /**
-     * Returns selected schema.
-     */
-    public String getSelectedSchema() {
-        String schema = (String) schemaSelector.getSelectedItem();
-        return "".equals(schema) ? null : schema;
-    }
-
-    /**
-     * Returns the tableNamePattern.
-     */
-    public String getTableNamePattern() {
+    String getTableNamePattern() {
         return "".equals(tableNamePatternField.getText()) ? null : tableNamePatternField
                 .getText();
     }
 
-    public String getMeaningfulPk() {
+    String getMeaningfulPk() {
         return "".equals(meaningfulPk.getText()) ? null : meaningfulPk
                 .getText();
     }
 
-    /**
-     * Returns the procedure name pattern.
-     */
-    public String getProcedureNamePattern() {
+    String getProcedureNamePattern() {
         return "".equals(procNamePatternField.getText()) ? null : procNamePatternField
                 .getText();
     }
 
-    /**
-     * Returns configured naming strategy
-     */
-    public String getNamingStrategy() {
-        return strategy;
+    String getNamingStrategy() {
+        return (String) strategyCombo.getSelectedItem();
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/190ab7c7/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/merge/DbMigrateOptionsDialog.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/merge/DbMigrateOptionsDialog.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/merge/DbMigrateOptionsDialog.java
index b3fb929..d044b30 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/merge/DbMigrateOptionsDialog.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/merge/DbMigrateOptionsDialog.java
@@ -19,158 +19,21 @@
 
 package org.apache.cayenne.modeler.dialog.db.merge;
 
-import java.awt.BorderLayout;
-import java.awt.FlowLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.util.Collection;
 
-import javax.swing.DefaultComboBoxModel;
-import javax.swing.JButton;
-import javax.swing.JComboBox;
-import javax.swing.JDialog;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-
-import org.apache.cayenne.modeler.Application;
-import org.apache.cayenne.modeler.util.CayenneDialog;
-
 import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-
-public class DbMigrateOptionsDialog extends CayenneDialog {
-	private static final long serialVersionUID = 1L;
-	public static final int CANCEL = 0;
-    public static final int SELECT = 1;
-
-	protected JLabel schemaLabel;
-	protected JLabel catalogLabel;
-    protected JComboBox<String> catalogSelector;
-    protected JComboBox<String> schemaSelector;
-    protected JButton selectButton;
-    protected JButton cancelButton;
-    protected int choice;
-    
-    public DbMigrateOptionsDialog(Collection<String> catalogs, Collection<String> schemas, String dbUserName) {
-        super(Application.getFrame(), "Migrate DB Schema: Select Catalog and Schema");
-        init();
-        initController();
-        initFromModel(catalogs, schemas, dbUserName);
-
-        pack();
-        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-        setModal(true);
-        centerWindow();    	
-    }
-    
-    protected void init() {
-        selectButton = new JButton("Continue");
-        cancelButton = new JButton("Cancel");
-        catalogSelector = new JComboBox<>();
-        schemaSelector = new JComboBox<>();
-        FormLayout layout = new FormLayout(
-                "right:pref, 3dlu, fill:max(170dlu;pref):grow",
-                "");
-        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
-        builder.setDefaultDialogBorder();
-
-        catalogLabel = builder.append("Select Catalog:", catalogSelector, true);
-        schemaLabel = builder.append("Select Schema:", schemaSelector);
-
-        JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
-        buttons.add(selectButton);
-        buttons.add(cancelButton);
-        
-        getContentPane().setLayout(new BorderLayout());
-        getContentPane().add(builder.getPanel(), BorderLayout.CENTER);
-        getContentPane().add(buttons, BorderLayout.SOUTH);        
-    }
-    
-    protected void initController() {
-        selectButton.addActionListener(new ActionListener() {
-
-            public void actionPerformed(ActionEvent e) {
-                processSelect();
-            }
-        });
-
-        cancelButton.addActionListener(new ActionListener() {
-
-            public void actionPerformed(ActionEvent e) {
-                processCancel();
-            }
-        });
-    }
-    
-    private void processSelect() {
-        choice = SELECT;
-        setVisible(false);
-    }
-
-    private void processCancel() {
-    	schemaSelector.setSelectedItem(null);
-        choice = CANCEL;
-        setVisible(false);
-    }
-    
-    protected void initFromModel(Collection<String> catalogs, Collection<String> schemas, String dbUserName) {
-
-        this.choice = CANCEL;
-
-        if(!schemas.isEmpty()) {
-            schemaLabel.setVisible(true);
-            schemaSelector.setModel(new DefaultComboBoxModel<>(schemas.toArray(new String[0])));
-            schemaSelector.setVisible(true);
-        } else {
-            schemaLabel.setVisible(false);
-            schemaSelector.setVisible(false);
-        }
-
-        if(!catalogs.isEmpty()) {
-            catalogLabel.setVisible(true);
-            catalogSelector.setModel(new DefaultComboBoxModel<>(catalogs.toArray(new String[0])));
-            catalogSelector.setVisible(true);
-        } else {
-            catalogLabel.setVisible(false);
-            catalogSelector.setVisible(false);
-        }
-
-        if (dbUserName == null) {
-            return;
-        }
-
-        // select schema belonging to the user
-        for (String schema : schemas) {
-            if (dbUserName.equalsIgnoreCase(schema)) {
-                schemaSelector.setSelectedItem(schema);
-                break;
-            }
-        }
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.dialog.db.DbActionOptionsDialog;
 
-        for(String catalog : catalogs) {
-            if(dbUserName.equalsIgnoreCase(catalog)) {
-                catalogSelector.setSelectedItem(catalog);
-                break;
-            }
-        }
-    }
+public class DbMigrateOptionsDialog extends DbActionOptionsDialog {
     
-    /**
-     * Returns selected schema.
-     */
-    public String getSelectedSchema() {
-    	return (String) schemaSelector.getSelectedItem();
+    public DbMigrateOptionsDialog(Collection<String> catalogs, Collection<String> schemas,
+                                  String defaultCatalog, String defaultSchema) {
+        super(Application.getFrame(), "Migrate DB Schema: Select Catalog and Schema",
+                catalogs, schemas, defaultCatalog, defaultSchema);
     }
 
-    public String getSelectedCatalog() {
-        return (String) catalogSelector.getSelectedItem();
-    }
-    
-    public int getChoice() {
-    	return choice;
-    }
-    
-    public void showDialog() {
-    	setVisible(true);
+    @Override
+    protected void initForm(DefaultFormBuilder builder) {
     }
 }