preparing new "connection tree" feature

This commit is contained in:
Ralf Wisser
2022-12-20 14:43:03 +01:00
parent a19da3c599
commit 2d166074f1
8 changed files with 133 additions and 60 deletions
@@ -1316,7 +1316,7 @@ public class DataModelEditor extends javax.swing.JDialog {
protected void checkPK(Table table) {
try {
if (!dbConnectionDialog.isConnected) {
dbConnectionDialog = new DbConnectionDialog(this, dbConnectionDialog, JailerVersion.APPLICATION_NAME, executionContext);
dbConnectionDialog = new DbConnectionDialog(this, dbConnectionDialog, JailerVersion.APPLICATION_NAME, null, executionContext);
}
if (dbConnectionDialog.isConnected || dbConnectionDialog.connect("Check Primary Keys")) {
BasicDataSource dataSource = UIUtil.createBasicDataSource(this, dbConnectionDialog.currentConnection.driverClass, dbConnectionDialog.currentConnection.url, dbConnectionDialog.currentConnection.user, dbConnectionDialog.getPassword(), 0, dbConnectionDialog.currentJarURLs());
@@ -1338,7 +1338,7 @@ public abstract class DataModelManagerDialog extends javax.swing.JFrame {
}
private void initConnectionDialog(boolean all) {
DbConnectionDialog dialog = new DbConnectionDialog(this, JailerVersion.APPLICATION_NAME, all? infoBarConnection : infoBarRecUsedConnection, executionContext, false, !all) {
DbConnectionDialog dialog = new DbConnectionDialog(this, JailerVersion.APPLICATION_NAME, all? infoBarConnection : infoBarRecUsedConnection, null, executionContext, false, !all) {
@Override
protected boolean isAssignedToDataModel(String dataModelFolder) {
return modelList.contains(dataModelFolder);
@@ -2548,7 +2548,7 @@ public abstract class DataModelManagerDialog extends javax.swing.JFrame {
DbConnectionDialog dbConnectionDialog = new DbConnectionDialog(this, applicationName,
new DMMDInfoBar("Connect with Database",
"Select a connection to the database to be analyzed, or create a new connection.\n" +
"New connections will be assigned to the datamodel \"" + modelDetails.get(currentModel).a + "\".", null), executionContext);
"New connections will be assigned to the datamodel \"" + modelDetails.get(currentModel).a + "\".", null), null, executionContext);
if (dbConnectionDialog.connect("Analyze Database")) {
List<String> args = new ArrayList<String>();
args.add("build-model-wo-merge");
@@ -202,8 +202,6 @@ public class DbConnectionDialog extends javax.swing.JDialog {
return connect(reason, false);
}
private boolean located = false;
private Font font = new JLabel("normal").getFont();
private Font normal = font.deriveFont(font.getStyle() & ~Font.BOLD, font.getSize());
private Font bold = font.deriveFont(font.getStyle() | Font.BOLD, font.getSize());
@@ -265,13 +263,19 @@ public class DbConnectionDialog extends javax.swing.JDialog {
}
private final InfoBar infoBar;
private final String currentModelSubfolder;
private final boolean dataModelAware;
private final DataModelChanger dataModelChanger;
private final boolean showOnlyRecentyUsedConnections;
public interface DataModelChanger {
void change(String dataModelSubfolder);
void onConnectionListChanged();
void afterConnect();
}
/** Creates new form DbConnectionDialog */
public DbConnectionDialog(Window parent, DbConnectionDialog other, String applicationName, ExecutionContext executionContext) {
this(parent, applicationName, other.infoBar == null? null : new InfoBar(other.infoBar), executionContext);
public DbConnectionDialog(Window parent, DbConnectionDialog other, String applicationName, DataModelChanger dataModelChanger, ExecutionContext executionContext) {
this(parent, applicationName, other.infoBar == null? null : new InfoBar(other.infoBar), dataModelChanger, executionContext);
this.isConnected = other.isConnected;
this.connectionList = other.connectionList;
if (other.currentConnection != null) {
@@ -288,8 +292,8 @@ public class DbConnectionDialog extends javax.swing.JDialog {
*
* @param applicationName application name. Used to create the name of the demo database alias.
*/
public DbConnectionDialog(Window parent, String applicationName, InfoBar infoBar, ExecutionContext executionContext) {
this(parent, applicationName, infoBar, executionContext, true, false);
public DbConnectionDialog(Window parent, String applicationName, InfoBar infoBar, DataModelChanger dataModelChanger, ExecutionContext executionContext) {
this(parent, applicationName, infoBar, dataModelChanger, executionContext, true, false);
}
/**
@@ -298,13 +302,13 @@ public class DbConnectionDialog extends javax.swing.JDialog {
* @param applicationName application name. Used to create the name of the demo database alias.
* @param showOnlyRecentyUsedConnections
*/
public DbConnectionDialog(Window parent, String applicationName, InfoBar infoBar, ExecutionContext executionContext, boolean dataModelAware, boolean showOnlyRecentyUsedConnections) {
public DbConnectionDialog(Window parent, String applicationName, InfoBar infoBar, DataModelChanger dataModelChanger, ExecutionContext executionContext, boolean dataModelAware, boolean showOnlyRecentyUsedConnections) {
super(parent);
setModal(true);
this.dataModelChanger = dataModelChanger;
this.executionContext = executionContext;
this.parent = parent;
this.infoBar = infoBar;
this.currentModelSubfolder = DataModelManager.getCurrentModelSubfolder(executionContext);
this.dataModelAware = dataModelAware;
this.showOnlyRecentyUsedConnections = showOnlyRecentyUsedConnections;
loadConnectionList(showOnlyRecentyUsedConnections);
@@ -563,7 +567,7 @@ public class DbConnectionDialog extends javax.swing.JDialog {
copy.setEnabled(currentConnection != null);
jButton1.setEnabled(currentConnection != null && selectedRowIndex >= 0 && selectedRowIndex < connectionList.size());
warnOnConnect = !(selectedRowIndex < 0 || isAssignedToDataModel(selectedRowIndex));
if (currentModelSubfolder == null && warnOnConnect) {
if (DataModelManager.getCurrentModelSubfolder(executionContext) == null && warnOnConnect) {
warnOnConnect = false;
jButton1.setEnabled(false);
}
@@ -752,9 +756,9 @@ public class DbConnectionDialog extends javax.swing.JDialog {
@Override
public int compare(ConnectionInfo o1, ConnectionInfo o2) {
if (dataModelAware) {
if (currentModelSubfolder != null) {
boolean c1 = currentModelSubfolder.equals(o1.dataModelFolder);
boolean c2 = currentModelSubfolder.equals(o2.dataModelFolder);
if (DataModelManager.getCurrentModelSubfolder(executionContext) != null) {
boolean c1 = DataModelManager.getCurrentModelSubfolder(executionContext).equals(o1.dataModelFolder);
boolean c2 = DataModelManager.getCurrentModelSubfolder(executionContext).equals(o2.dataModelFolder);
if (c1 && !c2) return -1;
if (!c1 && c2) return 1;
@@ -1128,7 +1132,9 @@ public class DbConnectionDialog extends javax.swing.JDialog {
}
if (warnOnConnect) {
if (JOptionPane.YES_OPTION != JOptionPane.showConfirmDialog(mainPanel, "Connection is not associated with " + (currentModelSubfolder == null? "any data model." : ("data model \"" + currentModelSubfolder + "\".")) + "\nDo you still want to connect?", "Connect", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE)) {
boolean noDM = DataModelManager.getCurrentModelSubfolder(executionContext) == null;
if (JOptionPane.YES_OPTION != JOptionPane.showConfirmDialog(mainPanel, "Connection is not associated with " + (noDM? "any data model." : ("data model \"" + DataModelManager.getCurrentModelSubfolder(executionContext) + "\".")) + "\n"
+ (noDM || dataModelChanger == null? "Do you still want to connect?" : "Do you want to change data model and connect?"), "Connect", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE)) {
return;
}
}
@@ -1145,7 +1151,13 @@ public class DbConnectionDialog extends javax.swing.JDialog {
isConnected = true;
ok = true;
executionContext.setCurrentConnectionAlias(currentConnection.alias);
if (dataModelChanger != null && DataModelManager.getCurrentModelSubfolder(executionContext) != null && warnOnConnect) {
dataModelChanger.change(currentConnection.dataModelFolder);
}
onConnect(currentConnection);
if (dataModelChanger != null) {
dataModelChanger.afterConnect();
}
if (currentConnection.alias != null && !"".equals(currentConnection.alias)) {
UISettings.addRecentConnectionAliases(currentConnection.alias);
}
@@ -1329,7 +1341,7 @@ public class DbConnectionDialog extends javax.swing.JDialog {
}
protected boolean isAssignedToDataModel(String dataModelFolder) {
String fn = currentModelSubfolder;
String fn = DataModelManager.getCurrentModelSubfolder(executionContext);
return fn == null && dataModelFolder == null || (fn != null && fn.equals(dataModelFolder));
}
@@ -204,9 +204,9 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
pack();
updateTitle(extractionModelEditor.needsSave);
if (initDbConnectionDialog != null) {
dbConnectionDialog = new DbConnectionDialog(this, initDbConnectionDialog, JailerVersion.APPLICATION_NAME, executionContext);
dbConnectionDialog = new DbConnectionDialog(this, initDbConnectionDialog, JailerVersion.APPLICATION_NAME, null, executionContext);
} else {
dbConnectionDialog = new DbConnectionDialog(this, JailerVersion.APPLICATION_NAME, null, executionContext);
dbConnectionDialog = new DbConnectionDialog(this, JailerVersion.APPLICATION_NAME, null, null, executionContext);
}
dbConnectionDialog.autoConnect();
@@ -1164,7 +1164,7 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
DataBrowser dataBrowser;
try {
UIUtil.setWaitCursor(this);
dataBrowser = new DataBrowser(extractionModelEditor.dataModel, root, condition, dbConnectionDialog, null, true, executionContext);
dataBrowser = new DataBrowser(extractionModelEditor.dataModel, root, condition, dbConnectionDialog, null, executionContext);
if (dataBrowser.isReady()) {
dataBrowser.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
dataBrowser.setExtendedState(Frame.MAXIMIZED_BOTH);
@@ -1695,7 +1695,7 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
*/
public void setDbConnectionDialogClone(DbConnectionDialog dbConnectionDialog) {
try {
this.dbConnectionDialog = new DbConnectionDialog(this, dbConnectionDialog, JailerVersion.APPLICATION_NAME, executionContext);
this.dbConnectionDialog = new DbConnectionDialog(this, dbConnectionDialog, JailerVersion.APPLICATION_NAME, null, executionContext);
} finally {
updateMenuItems();
}
@@ -73,7 +73,7 @@ public class PrivilegedSessionProviderDialog extends javax.swing.JDialog {
);
final PrivilegedSessionProviderDialog dialog = new PrivilegedSessionProviderDialog(theParent);
ConnectionInfo ci = new ConnectionInfo();
final DbConnectionDialog connectionDialog = new DbConnectionDialog(theParent, JailerVersion.APPLICATION_NAME, infoBar, executionContext, true, false) {
final DbConnectionDialog connectionDialog = new DbConnectionDialog(theParent, JailerVersion.APPLICATION_NAME, infoBar, null, executionContext, true, false) {
@Override
protected boolean isAssignedToDataModel(String dataModelFolder) {
return true;
@@ -150,6 +150,7 @@ import net.sf.jailer.ui.DataModelManager;
import net.sf.jailer.ui.DataModelManagerDialog;
import net.sf.jailer.ui.DbConnectionDialog;
import net.sf.jailer.ui.DbConnectionDialog.ConnectionInfo;
import net.sf.jailer.ui.DbConnectionDialog.DataModelChanger;
import net.sf.jailer.ui.Environment;
import net.sf.jailer.ui.ExtractionModelFrame;
import net.sf.jailer.ui.ImportDialog;
@@ -182,13 +183,14 @@ import net.sf.jailer.ui.syntaxtextarea.DataModelBasedSQLCompletionProvider;
import net.sf.jailer.ui.syntaxtextarea.RSyntaxTextAreaWithSQLSyntaxStyle;
import net.sf.jailer.ui.util.AnimationController;
import net.sf.jailer.ui.util.CompoundIcon;
import net.sf.jailer.ui.util.CompoundIcon.Axis;
import net.sf.jailer.ui.util.RotatedIcon;
import net.sf.jailer.ui.util.SmallButton;
import net.sf.jailer.ui.util.TextIcon;
import net.sf.jailer.ui.util.UISettings;
import net.sf.jailer.ui.util.UpdateInfoManager;
import net.sf.jailer.ui.util.CompoundIcon.Axis;
import net.sf.jailer.util.CancellationHandler;
import net.sf.jailer.util.LogUtil;
import net.sf.jailer.util.Quoting;
import net.sf.jailer.util.SqlUtil;
@@ -326,12 +328,12 @@ public class DataBrowser extends javax.swing.JFrame {
* @param dbConnectionDialog DB-connection dialog
*/
public DataBrowser(final DataModel datamodel, final Table root, String condition,
DbConnectionDialog dbConnectionDialog, Map<String, String> schemaMapping, boolean embedded,
DbConnectionDialog dbConnectionDialog, Map<String, String> schemaMapping,
final ExecutionContext executionContext) throws Exception {
this.executionContext = executionContext;
this.datamodel = new Reference<DataModel>(datamodel);
this.dbConnectionDialog = dbConnectionDialog != null
? new DbConnectionDialog(this, dbConnectionDialog, DataBrowserContext.getAppName(), executionContext)
? new DbConnectionDialog(this, dbConnectionDialog, DataBrowserContext.getAppName(), createDataModelChanger(), executionContext)
: null;
this.borderBrowser = new AssociationListUI("Resolve", "Resolve selected Associations", true) {
private static final long serialVersionUID = 183805595423236039L;
@@ -342,9 +344,6 @@ public class DataBrowser extends javax.swing.JFrame {
}
};
executionContext.setUseRowIdsOnlyForTablesWithoutPK(true);
if (embedded) {
DataBrowserContext.setSupportsDataModelUpdates(false);
}
initComponents();
initMenu();
initNavTree();
@@ -836,11 +835,6 @@ public class DataBrowser extends javax.swing.JFrame {
mediumLayoutRadioButtonMenuItem.setSelected(true);
setTitle(DataBrowserContext.getAppName(false));
if (embedded) {
analyseMenuItem.setEnabled(false);
dataModelEditorjMenuItem.setEnabled(false);
analyseSQLMenuItem1.setEnabled(false);
}
// L&F can no longer be changed
jSeparator6.setVisible(false);
@@ -1321,6 +1315,69 @@ public class DataBrowser extends javax.swing.JFrame {
initDnD(this);
}
private String cDTmpFilePrefix = Environment.newFile(".tmpdmc-" + System.currentTimeMillis()).getPath();
private DataModelChanger createDataModelChanger() {
// TODO Auto-generated method stub
return new DataModelChanger() {
private Runnable afterReconnectAction = null;
@Override
public void onConnectionListChanged() {
}
Map<String, Map<String, String>> schemamappings = new HashMap<String, Map<String,String>>();
@Override
public void change(String dataModelSubfolder) {
// TODO Auto-generated method stub
afterReconnectAction = null;
String sFile = cDTmpFilePrefix + DataModelManager.getCurrentModelSubfolder(executionContext);
new File(sFile).deleteOnExit();
try {
desktop.storeSession(sFile);
} catch (IOException e1) {
LogUtil.warn(e1);
}
schemamappings.put(dataModelSubfolder, desktop.schemaMapping);
DataModelManager.setCurrentModelSubfolder(dataModelSubfolder, executionContext);
Map<String, String> schemamapping = schemamappings.get(dataModelSubfolder);
if (schemamapping == null) {
schemamapping = new HashMap<String, String>();
}
try {
String sessionFile = cDTmpFilePrefix + dataModelSubfolder;
desktop.reloadDataModel(schemamapping, new File(sessionFile).exists(), false);
if (new File(sessionFile).exists()) {
afterReconnectAction = () -> {
try {
desktop.restoreSession(null, DataBrowser.this, sessionFile, true);
} catch (Exception e) {
LogUtil.warn(e);
}
};
}
desktop.updateBookmarksMenu();
} catch (Exception e) {
UIUtil.showException(DataBrowser.this, "Error", e);
}
}
@Override
public void afterConnect() {
if (afterReconnectAction != null) {
afterReconnectAction.run();
afterReconnectAction = null;
}
}
};
}
private static Timer tabSelectionAnimationTimer = null;
private static synchronized void initTabSelectionAnimationManager() {
@@ -1475,7 +1532,7 @@ public class DataBrowser extends javax.swing.JFrame {
protected void setConnection(DbConnectionDialog dbConnectionDialog) throws Exception {
if (dbConnectionDialog != null) {
dbConnectionDialog = new DbConnectionDialog(this, dbConnectionDialog, DataBrowserContext.getAppName(),
executionContext);
createDataModelChanger(), executionContext);
}
this.dbConnectionDialog = dbConnectionDialog;
desktop.dbConnectionDialog = dbConnectionDialog;
@@ -3124,7 +3181,7 @@ public class DataBrowser extends javax.swing.JFrame {
String sqlFile = UIUtil.choseFile(null, ".", "Data Import", ".sql", this, false, true);
if (sqlFile != null) {
DbConnectionDialog dcd = new DbConnectionDialog(this, dbConnectionDialog,
DataBrowserContext.getAppName(), executionContext);
DataBrowserContext.getAppName(), createDataModelChanger(), executionContext);
if (dcd.connect("Data Import")) {
List<String> args = new ArrayList<String>();
args.add("import");
@@ -3550,7 +3607,7 @@ public class DataBrowser extends javax.swing.JFrame {
boolean maximize, ExecutionContext executionContext, DataBrowser theDataBrowser) throws Exception {
final DataBrowser dataBrowser = theDataBrowser != null ? theDataBrowser
: new DataBrowser(datamodel, null, "", null,
ExecutionContext.getSchemaMapping(CommandLineInstance.getInstance().rawschemamapping), false,
ExecutionContext.getSchemaMapping(CommandLineInstance.getInstance().rawschemamapping),
executionContext);
dataBrowser.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
dataBrowser.setVisible(true);
@@ -3558,10 +3615,10 @@ public class DataBrowser extends javax.swing.JFrame {
if (dbConnectionDialog == null) {
dbConnectionDialog = new DbConnectionDialog(dataBrowser, DataBrowserContext.getAppName(), null,
executionContext);
dataBrowser.createDataModelChanger(), executionContext);
} else {
dbConnectionDialog = new DbConnectionDialog(dataBrowser, dbConnectionDialog,
DataBrowserContext.getAppName(), executionContext);
DataBrowserContext.getAppName(), dataBrowser.createDataModelChanger(), executionContext);
}
dbConnectionDialog.autoConnect();
if (dbConnectionDialog.isConnected || dbConnectionDialog.connect(DataBrowserContext.getAppName(true))) {
@@ -3642,7 +3699,7 @@ public class DataBrowser extends javax.swing.JFrame {
.getSchemaMapping(CommandLineInstance.getInstance().rawschemamapping);
datamodel = new DataModel(null, null, schemaMapping, null, new PrimaryKeyFactory(executionContext),
executionContext, true, null);
final DataBrowser databrowser = new DataBrowser(datamodel, null, "", null, schemaMapping, false,
final DataBrowser databrowser = new DataBrowser(datamodel, null, "", null, schemaMapping,
executionContext);
UIUtil.invokeLater(new Runnable() {
@Override
@@ -5916,5 +5973,15 @@ public class DataBrowser extends javax.swing.JFrame {
tbZoomOutIcon = UIUtil.scaleIcon(new JLabel(""), UIUtil.readImage("/tb_zoomout.png"));
connectionIcon = UIUtil.scaleIcon(new JLabel(""), UIUtil.readImage("/connection.png"));
}
// TODO
// TODO reconnect: instead of caching sesions: waitDialog.setOpaque(0.2?); ...1sec...waitDialog.setOpaque(1);
// TODO wait cursor initially
// TODO
// TODO test: state after connection failed?
// TODO
// TODO postgres "daterange": what about arrays ("_.*")? Patterns in key of <sqlExpressionRule>?
}
@@ -24,17 +24,6 @@ import net.sf.jailer.JailerVersion;
*/
public class DataBrowserContext {
private static boolean supportsDataModelUpdates = true;
public static synchronized boolean isSupportsDataModelUpdates() {
return supportsDataModelUpdates;
}
public static synchronized void setSupportsDataModelUpdates(
boolean supportsDataModelUpdates) {
DataBrowserContext.supportsDataModelUpdates = supportsDataModelUpdates;
}
public static String getAppName(boolean shortName) {
return JailerVersion.APPLICATION_NAME + " " + JailerVersion.VERSION + (shortName? "" : " - Relational Data Browser");
}
@@ -3162,17 +3162,18 @@ public abstract class Desktop extends JDesktopPane {
* Reloads the data model and replaces the tables in all browser windows.
*/
public void reloadDataModel(Map<String, String> schemamapping) throws Exception {
reloadDataModel(schemamapping, true);
reloadDataModel(schemamapping, true, true);
}
/**
* Reloads the data model and replaces the tables in all browser windows.
* @param restoreSess
*/
public void reloadDataModel(Map<String, String> schemamapping, boolean forAll) throws Exception {
public void reloadDataModel(Map<String, String> schemamapping, boolean restoreSess, boolean forAll) throws Exception {
if (forAll) {
for (Desktop desktop : desktops) {
if (desktop != this) {
desktop.reloadDataModel(desktop.schemaMapping, false);
desktop.reloadDataModel(desktop.schemaMapping, restoreSess, false);
}
}
}
@@ -3184,7 +3185,9 @@ public abstract class Desktop extends JDesktopPane {
pFrame = this;
}
String filename = Environment.newFile(".tempsession-" + System.currentTimeMillis()).getPath();
storeSession(filename);
if (restoreSess) {
storeSession(filename);
}
DataModel newModel = new DataModel(schemamapping, executionContext, false);
datamodel.set(newModel);
@@ -3192,9 +3195,11 @@ public abstract class Desktop extends JDesktopPane {
onNewDataModel();
restoreSession(null, pFrame, filename);
File file = new File(filename);
file.delete();
if (restoreSess) {
restoreSession(null, pFrame, filename);
File file = new File(filename);
file.delete();
}
} catch (Throwable e) {
UIUtil.showException(this, "Error", e, session);
}
@@ -3240,7 +3245,7 @@ public abstract class Desktop extends JDesktopPane {
schemaMapping.clear();
schemaMapping.putAll(mapping);
parentFrame.updateStatusBar();
reloadDataModel(mapping, !silent);
reloadDataModel(mapping, true, !silent);
reloadRoots();
}
} catch (Exception e) {