GP-4867 Added BSim Server connection toggle for H2 and Postgres. Fixed various related bugs.

This commit is contained in:
ghidra1 2024-08-28 15:46:47 -04:00
parent 6a94f1f7ab
commit 249d91f0a1
31 changed files with 530 additions and 255 deletions

View File

@ -42,6 +42,8 @@ src/main/help/help/topics/BSimSearchPlugin/images/BSimSearchDialog.png||GHIDRA||
src/main/help/help/topics/BSimSearchPlugin/images/ManageServersDialog.png||GHIDRA||||END|
src/main/resources/bsim.log4j.xml||GHIDRA||||END|
src/main/resources/images/checkmark_yellow.gif||GHIDRA||||END|
src/main/resources/images/connect.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/disconnect.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/flag_green.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
src/main/resources/images/preferences-desktop-user-password.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
src/main/resources/images/preferences-web-browser-shortcuts-32.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|

View File

@ -14,4 +14,7 @@ icon.bsim.results.status.ignored = checkmark_yellow.gif
icon.bsim.functions.table = FunctionScope.gif
icon.bsim.connected = connect.png
icon.bsim.disconnected = disconnect.png
[Dark Defaults]

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -71,22 +71,17 @@ public class AddProgramToH2BSimDatabaseScript extends GhidraScript {
askValues("Select Database File", null, values);
File h2DbFile = values.getFile(DATABASE);
BSimServerInfo serverInfo =
new BSimServerInfo(DBType.file, null, 0, h2DbFile.getAbsolutePath());
FunctionDatabase h2Database = null;
try {
BSimServerInfo serverInfo =
new BSimServerInfo(DBType.file, null, 0, h2DbFile.getAbsolutePath());
h2Database = BSimClientFactory.buildClient(serverInfo, false);
BSimH2FileDataSource bds =
BSimH2FileDBConnectionManager.getDataSourceIfExists(h2Database.getServerInfo());
if (bds == null) {
popup(h2DbFile.getAbsolutePath() + " is not an H2 database file");
return;
}
if (bds.getActiveConnections() > 0) {
popup("There is an existing connection to the database.");
return;
}
BSimH2FileDataSource existingBDS =
BSimH2FileDBConnectionManager.getDataSourceIfExists(serverInfo);
if (existingBDS != null && existingBDS.getActiveConnections() > 0) {
popup("There is an existing connection to the database.");
return;
}
try (FunctionDatabase h2Database = BSimClientFactory.buildClient(serverInfo, false)) {
h2Database.initialize();
DatabaseInformation dbInfo = h2Database.getInfo();
@ -169,11 +164,13 @@ public class AddProgramToH2BSimDatabaseScript extends GhidraScript {
}
finally {
if (h2Database != null) {
h2Database.close();
if (existingBDS == null) {
// Dispose database source if it did not previously exist
BSimH2FileDataSource bds =
BSimH2FileDBConnectionManager.getDataSourceIfExists(h2Database.getServerInfo());
bds.dispose();
BSimH2FileDBConnectionManager.getDataSourceIfExists(serverInfo);
if (bds != null) {
bds.dispose();
}
}
}
}

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -31,7 +31,6 @@ import ghidra.features.bsim.query.file.BSimH2FileDBConnectionManager;
import ghidra.features.bsim.query.file.BSimH2FileDBConnectionManager.BSimH2FileDataSource;
import ghidra.features.bsim.query.protocol.*;
import ghidra.util.MessageType;
import ghidra.util.Msg;
public class CreateH2BSimDatabaseScript extends GhidraScript {
private static final String NAME = "Database Name";
@ -80,31 +79,27 @@ public class CreateH2BSimDatabaseScript extends GhidraScript {
askValues("Enter Database Parameters",
"Enter values required to create a new BSim H2 database.", values);
FunctionDatabase h2Database = null;
try {
String databaseName = values.getString(NAME);
File dbDir = values.getFile(DIRECTORY);
String template = values.getChoice(DATABASE_TEMPLATE);
String functionTagsCSV = values.getString(FUNCTION_TAGS);
List<String> tags = parseCSV(functionTagsCSV);
String databaseName = values.getString(NAME);
File dbDir = values.getFile(DIRECTORY);
String template = values.getChoice(DATABASE_TEMPLATE);
String functionTagsCSV = values.getString(FUNCTION_TAGS);
List<String> tags = parseCSV(functionTagsCSV);
String exeCatCSV = values.getString(EXECUTABLE_CATEGORIES);
List<String> cats = parseCSV(exeCatCSV);
String exeCatCSV = values.getString(EXECUTABLE_CATEGORIES);
List<String> cats = parseCSV(exeCatCSV);
File dbFile = new File(dbDir, databaseName);
File dbFile = new File(dbDir, databaseName);
BSimServerInfo serverInfo =
new BSimServerInfo(DBType.file, null, 0, dbFile.getAbsolutePath());
BSimServerInfo serverInfo =
new BSimServerInfo(DBType.file, null, 0, dbFile.getAbsolutePath());
h2Database = BSimClientFactory.buildClient(serverInfo, false);
BSimH2FileDataSource bds =
BSimH2FileDBConnectionManager.getDataSourceIfExists(h2Database.getServerInfo());
if (bds.getActiveConnections() > 0) {
//if this happens, there is a connection to the database but the
//database file was deleted
Msg.showError(this, null, "Connection Error",
"There is an existing connection to the database!");
return;
}
BSimH2FileDataSource existingBDS =
BSimH2FileDBConnectionManager.getDataSourceIfExists(serverInfo);
if (existingBDS != null && existingBDS.getActiveConnections() > 0) {
popup("There is an existing connection to the database.");
return;
}
try (FunctionDatabase h2Database = BSimClientFactory.buildClient(serverInfo, false)) {
CreateDatabase command = new CreateDatabase();
command.info = new DatabaseInformation();
@ -140,11 +135,13 @@ public class CreateH2BSimDatabaseScript extends GhidraScript {
popup("Database " + values.getString(NAME) + " created successfully!");
}
finally {
if (h2Database != null) {
h2Database.close();
if (existingBDS == null) {
// Dispose database source if it did not previously exist
BSimH2FileDataSource bds =
BSimH2FileDBConnectionManager.getDataSourceIfExists(h2Database.getServerInfo());
bds.dispose();
BSimH2FileDBConnectionManager.getDataSourceIfExists(serverInfo);
if (bds != null) {
bds.dispose();
}
}
}

View File

@ -57,18 +57,24 @@
entry shows a name for the BSim database, its type (postgres, elastic, or file), a host ip
and port (if applicable), and finally the number of active connections.</P>
<P>There are three primary actions for this dialog:</P>
<P>There are four primary actions for this dialog:</P>
<A name="Manage_Servers_Actions"></A>
<UL>
<LI><IMG alt="" src="Icons.ADD_ICON">&nbsp;Add a new database/server definition - a
Define Server Dialog will be shown.</LI>
<LI><IMG alt="" src="Icons.ADD_ICON">&nbsp;Add a new BSim database/server definition - an
Add BSim Server Dialog will be shown.</LI>
<LI><IMG alt="" src="Icons.DELETE_ICON">&nbsp;Delete a database/server definition - The
selected entry will be deleted.</LI>
selected entry will be deleted. This action will force an immediate disconnect for an
active/idle connection and should be used with care.</LI>
<LI><IMG alt="" src="icon.bsim.disconnected"><IMG alt="" src="icon.bsim.connected">&nbsp;
Connect or disconnect an inactive database/server connection. This action is not supported
by Elastic database servers.</LI>
<LI><IMG alt="" src="icon.bsim.change.password">&nbsp;Change password - A change password
dialog will appear for the selected entry</LI>
dialog will appear for the selected database server. Action is disabled for databases
which do not use a password (e.g., Local H2 File database).</LI>
</UL>
<H3><A name="Add_Server_Definition_Dialog">Defining a new BSim server/database</A></H3>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -72,7 +72,7 @@ public class BSimSearchPlugin extends ProgramPlugin {
private Set<BSimSearchResultsProvider> searchResultsProviders = new HashSet<>();
private Set<BSimOverviewProvider> overviewProviders = new HashSet<>();
private BSimServerManager serverManager = new BSimServerManager();
private BSimServerManager serverManager = BSimServerManager.getBSimServerManager();
private BSimSearchService searchService;
private BSimServerCache lastUsedServerCache = null;

View File

@ -4,25 +4,25 @@
* Licensed 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 ghidra.features.bsim.gui.search.dialog;
package ghidra.features.bsim.gui;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import ghidra.features.bsim.query.BSimPostgresDBConnectionManager;
import ghidra.features.bsim.gui.search.dialog.BSimServerManagerListener;
import ghidra.features.bsim.query.*;
import ghidra.features.bsim.query.BSimPostgresDBConnectionManager.BSimPostgresDataSource;
import ghidra.features.bsim.query.BSimServerInfo;
import ghidra.features.bsim.query.BSimServerInfo.DBType;
import ghidra.features.bsim.query.file.BSimH2FileDBConnectionManager;
import ghidra.features.bsim.query.file.BSimH2FileDBConnectionManager.BSimH2FileDataSource;
@ -36,12 +36,24 @@ import ghidra.util.Swing;
* Managers BSim database server definitions and connections
*/
public class BSimServerManager {
// TODO: Do not allow removal of active server. Dispose data source when removed.
private static BSimServerManager instance;
/**
* Get static singleton instance for BSimServerManager
* @return BSimServerManager instance
*/
static synchronized BSimServerManager getBSimServerManager() {
if (instance == null) {
instance = new BSimServerManager();
}
return instance;
}
private Set<BSimServerInfo> serverInfos = new HashSet<>();
private List<BSimServerManagerListener> listeners = new CopyOnWriteArrayList<>();
public BSimServerManager() {
private BSimServerManager() {
List<File> files = Application.getUserSettingsFiles("bsim", ".server.properties");
for (File file : files) {
BSimServerInfo info = readBsimServerInfoFile(file);
@ -51,6 +63,10 @@ public class BSimServerManager {
}
}
/**
* Get list of defined servers. Method must be invoked from swing thread only.
* @return list of defined servers
*/
public Set<BSimServerInfo> getServerInfos() {
return new HashSet<>(serverInfos);
}
@ -108,6 +124,10 @@ public class BSimServerManager {
return serverFile.delete();
}
/**
* Add server to list. Method must be invoked from swing thread only.
* @param newServerInfo new BSim DB server
*/
public void addServer(BSimServerInfo newServerInfo) {
if (saveBSimServerInfo(newServerInfo)) {
serverInfos.add(newServerInfo);
@ -115,28 +135,42 @@ public class BSimServerManager {
}
}
public boolean removeServer(BSimServerInfo info, boolean force) {
private static boolean disposeServer(BSimServerInfo info, boolean force) {
DBType dbType = info.getDBType();
if (dbType == DBType.file) {
BSimH2FileDataSource ds = BSimH2FileDBConnectionManager.getDataSource(info);
int active = ds.getActiveConnections();
if (active != 0) {
if (!force) {
BSimH2FileDataSource ds = BSimH2FileDBConnectionManager.getDataSourceIfExists(info);
if (ds != null) {
int active = ds.getActiveConnections();
if (active != 0 && !force) {
return false;
}
ds.dispose();
}
}
else if (dbType == DBType.postgres) {
BSimPostgresDataSource ds = BSimPostgresDBConnectionManager.getDataSource(info);
int active = ds.getActiveConnections();
if (active != 0) {
if (!force) {
BSimPostgresDataSource ds = BSimPostgresDBConnectionManager.getDataSourceIfExists(info);
if (ds != null) {
int active = ds.getActiveConnections();
if (active != 0 && !force) {
return false;
}
ds.dispose();
}
}
return true;
}
/**
* Remove BSim DB server from list. Method must be invoked from swing thread only.
* Specified server datasource will be dispose unless it is active or force is true.
* @param info BSim DB server to be removed
* @param force true if server datasource should be disposed even when active.
* @return true if server disposed and removed from list
*/
public boolean removeServer(BSimServerInfo info, boolean force) {
if (!disposeServer(info, force)) {
return false;
}
if (serverInfos.remove(info)) {
removeServerFileFromSettings(info);
notifyServerListChanged();
@ -160,26 +194,38 @@ public class BSimServerManager {
});
}
public static int getActiveConnections(BSimServerInfo serverInfo) {
/**
* Convenience method to get existing BSim JDBC datasource
* @param serverInfo BSim DB server info
* @return BSim DB datasource or null if not instantiated or server does not support a
* {@link BSimJDBCDataSource}.
*/
public static BSimJDBCDataSource getDataSourceIfExists(BSimServerInfo serverInfo) {
switch (serverInfo.getDBType()) {
case postgres:
BSimPostgresDataSource postgresDs =
BSimPostgresDBConnectionManager.getDataSourceIfExists(serverInfo);
if (postgresDs != null) {
return postgresDs.getActiveConnections();
}
break;
return BSimPostgresDBConnectionManager.getDataSourceIfExists(serverInfo);
case file:
BSimH2FileDataSource h2FileDs =
BSimH2FileDBConnectionManager.getDataSourceIfExists(serverInfo);
if (h2FileDs != null) {
return h2FileDs.getActiveConnections();
}
break;
return BSimH2FileDBConnectionManager.getDataSourceIfExists(serverInfo);
default:
break;
return null;
}
}
/**
* Convenience method to get a new or existing BSim JDBC datasource
* @param serverInfo BSim DB server info
* @return BSim DB datasource or null if server does not support a
* {@link BSimJDBCDataSource}.
*/
public static BSimJDBCDataSource getDataSource(BSimServerInfo serverInfo) {
switch (serverInfo.getDBType()) {
case postgres:
return BSimPostgresDBConnectionManager.getDataSource(serverInfo);
case file:
return BSimH2FileDBConnectionManager.getDataSource(serverInfo);
default:
return null;
}
return -1;
}
}

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -30,6 +30,7 @@ import docking.widgets.EmptyBorderButton;
import docking.widgets.combobox.GComboBox;
import docking.widgets.textfield.FloatingPointTextField;
import generic.theme.Gui;
import ghidra.features.bsim.gui.BSimServerManager;
import ghidra.features.bsim.query.BSimServerInfo;
import ghidra.features.bsim.query.description.DatabaseInformation;
import ghidra.features.bsim.query.facade.QueryDatabaseException;

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -16,6 +16,7 @@
package ghidra.features.bsim.gui.search.dialog;
import ghidra.features.bsim.gui.BSimSearchPlugin;
import ghidra.features.bsim.gui.BSimServerManager;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.listing.Program;
import ghidra.util.HelpLocation;

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -30,6 +30,7 @@ import docking.widgets.textfield.IntegerTextField;
import generic.theme.GIcon;
import ghidra.app.services.GoToService;
import ghidra.features.bsim.gui.BSimSearchPlugin;
import ghidra.features.bsim.gui.BSimServerManager;
import ghidra.features.bsim.gui.filters.BSimFilterType;
import ghidra.features.bsim.query.description.DatabaseInformation;
import ghidra.framework.plugintool.PluginTool;

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -16,21 +16,25 @@
package ghidra.features.bsim.gui.search.dialog;
import java.awt.BorderLayout;
import java.sql.Connection;
import java.sql.SQLException;
import javax.swing.*;
import org.bouncycastle.util.Arrays;
import docking.DialogComponentProvider;
import docking.DockingWindowManager;
import docking.action.DockingAction;
import docking.*;
import docking.action.*;
import docking.action.builder.ActionBuilder;
import docking.action.builder.ToggleActionBuilder;
import docking.widgets.OptionDialog;
import docking.widgets.PasswordChangeDialog;
import docking.widgets.table.GFilterTable;
import docking.widgets.table.GTable;
import generic.theme.GIcon;
import ghidra.features.bsim.gui.BSimServerManager;
import ghidra.features.bsim.query.*;
import ghidra.features.bsim.query.BSimServerInfo.DBType;
import ghidra.features.bsim.query.FunctionDatabase.Error;
import ghidra.features.bsim.query.FunctionDatabase.ErrorCategory;
import ghidra.framework.plugintool.PluginTool;
@ -42,15 +46,14 @@ import resources.Icons;
*/
public class BSimServerDialog extends DialogComponentProvider {
// TODO: Add connected status indicator (not sure how this relates to elastic case which will likely have a Session concept)
// TODO: Add "Disconnect" action (only works when active connections is 0; does not apply to elastic)
private PluginTool tool;
private BSimServerManager serverManager;
private BSimServerTableModel serverTableModel;
private GFilterTable<BSimServerInfo> filterTable;
private GFilterTable<BSimServerInfo> serverTable;
private BSimServerInfo lastAdded = null;
private ToggleDockingAction dbConnectionAction;
public BSimServerDialog(PluginTool tool, BSimServerManager serverManager) {
super("BSim Server Manager");
this.tool = tool;
@ -60,7 +63,7 @@ public class BSimServerDialog extends DialogComponentProvider {
addDismissButton();
setPreferredSize(600, 400);
notifyContextChanged(); // kick actions to initialized enabled state
setHelpLocation(new HelpLocation("BSimSearchPlugin","BSim_Servers_Dialog" ));
setHelpLocation(new HelpLocation("BSimSearchPlugin", "BSim_Servers_Dialog"));
}
@Override
@ -70,34 +73,101 @@ public class BSimServerDialog extends DialogComponentProvider {
}
private void createToolbarActions() {
HelpLocation help = new HelpLocation("BSimSearchPlugin","Manage_Servers_Actions" );
HelpLocation help = new HelpLocation("BSimSearchPlugin", "Manage_Servers_Actions");
DockingAction addServerAction =
new ActionBuilder("Add Server", "Dialog").toolBarIcon(Icons.ADD_ICON)
.helpLocation(help)
.onAction(e -> defineBsimServer())
.build();
new ActionBuilder("Add BSim Database", "Dialog").toolBarIcon(Icons.ADD_ICON)
.helpLocation(help)
.onAction(e -> defineBsimServer())
.build();
addAction(addServerAction);
DockingAction removeServerAction =
new ActionBuilder("Delete Server", "Dialog").toolBarIcon(Icons.DELETE_ICON)
.helpLocation(help)
.onAction(e -> deleteBsimServer())
.enabledWhen(c -> hasSelection())
.build();
new ActionBuilder("Delete BSim Database", "Dialog").toolBarIcon(Icons.DELETE_ICON)
.helpLocation(help)
.onAction(e -> deleteBsimServer())
.enabledWhen(c -> hasSelection())
.build();
addAction(removeServerAction);
DockingAction changePasswordAction = new ActionBuilder("Change User Password", "Dialog")
.helpLocation(help)
.toolBarIcon(new GIcon("icon.bsim.change.password"))
.onAction(e -> changePassword())
.enabledWhen(c -> hasSelection())
.build();
dbConnectionAction =
new ToggleActionBuilder("Toggle Database Connection", "Dialog").helpLocation(help)
.toolBarIcon(new GIcon("icon.bsim.disconnected"))
.onAction(e -> toggleSelectedJDBCDataSourceConnection())
.enabledWhen(c -> isNonActiveJDBCDataSourceSelected(c))
.build();
addAction(dbConnectionAction);
DockingAction changePasswordAction =
new ActionBuilder("Change User Password", "Dialog").helpLocation(help)
.toolBarIcon(new GIcon("icon.bsim.change.password"))
.onAction(e -> changePassword())
.enabledWhen(c -> canChangePassword())
.build();
addAction(changePasswordAction);
}
private void toggleSelectedJDBCDataSourceConnection() {
BSimServerInfo serverInfo = serverTable.getSelectedRowObject();
if (serverInfo == null || serverInfo.getDBType() == DBType.elastic) {
return;
}
BSimJDBCDataSource dataSource = BSimServerManager.getDataSourceIfExists(serverInfo);
if (dataSource == null) {
// connect
dataSource = BSimServerManager.getDataSource(serverInfo);
try (Connection connection = dataSource.getConnection()) {
// do nothing
}
catch (SQLException e) {
Msg.showError(this, rootPanel, "BSim Connection Failure", e.getMessage());
}
}
else {
dataSource.dispose();
}
serverTableModel.fireTableDataChanged();
notifyContextChanged();
}
private boolean isNonActiveJDBCDataSourceSelected(ActionContext c) {
BSimServerInfo serverInfo = serverTable.getSelectedRowObject();
if (serverInfo == null) {
return false;
}
// TODO: May need connection listener on dataSource to facilitate GUI update,
// although modal dialog avoids the issue somewhat
dbConnectionAction.setDescription(dbConnectionAction.getName());
ConnectionPoolStatus status = serverTableModel.getConnectionPoolStatus(serverInfo);
if (status.isActive) {
// Show connected icon
dbConnectionAction
.setToolBarData(new ToolBarData(new GIcon("icon.bsim.connected"), null));
dbConnectionAction.setSelected(true);
dbConnectionAction.setDescription("Disconnect idle BSim Database connection");
// disconnect permitted when no active connections
return status.activeCount == 0;
}
// Show disconnected icon (elastic always shown as disconnected)
dbConnectionAction
.setToolBarData(new ToolBarData(new GIcon("icon.bsim.disconnected"), null));
dbConnectionAction.setSelected(false);
dbConnectionAction.setDescription("Connect BSim Database");
// Action never enabled for elastic DB (i.e., does not use pooled JDBC data source)
return serverInfo.getDBType() != DBType.elastic;
}
private void changePassword() {
BSimServerInfo serverInfo = filterTable.getSelectedRowObject();
BSimServerInfo serverInfo = serverTable.getSelectedRowObject();
if (serverInfo == null) {
return;
}
@ -141,8 +211,13 @@ public class BSimServerDialog extends DialogComponentProvider {
}
}
private boolean canChangePassword() {
BSimServerInfo serverInfo = serverTable.getSelectedRowObject();
return serverInfo != null && serverInfo.getDBType() != DBType.file;
}
private void deleteBsimServer() {
BSimServerInfo selected = filterTable.getSelectedRowObject();
BSimServerInfo selected = serverTable.getSelectedRowObject();
if (selected != null) {
int answer =
OptionDialog.showYesNoDialog(getComponent(), "Delete Server Configuration?",
@ -152,7 +227,7 @@ public class BSimServerDialog extends DialogComponentProvider {
answer = OptionDialog.showOptionDialogWithCancelAsDefaultButton(getComponent(),
"Active Server Configuration!",
"Database connections are still active!\n" +
"Are you sure you want to delete server?",
"Are you sure you want to terminate connections and delete server?",
"Yes", OptionDialog.WARNING_MESSAGE);
if (answer == OptionDialog.YES_OPTION) {
serverManager.removeServer(selected, true);
@ -169,7 +244,7 @@ public class BSimServerDialog extends DialogComponentProvider {
if (newServerInfo != null) {
serverManager.addServer(newServerInfo);
lastAdded = newServerInfo;
Swing.runLater(() -> filterTable.setSelectedRowObject(newServerInfo));
Swing.runLater(() -> serverTable.setSelectedRowObject(newServerInfo));
}
}
@ -178,11 +253,11 @@ public class BSimServerDialog extends DialogComponentProvider {
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
serverTableModel = new BSimServerTableModel(serverManager);
filterTable = new GFilterTable<>(serverTableModel);
GTable table = filterTable.getTable();
serverTable = new GFilterTable<>(serverTableModel);
GTable table = serverTable.getTable();
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.getSelectionModel().addListSelectionListener(e -> notifyContextChanged());
panel.add(filterTable, BorderLayout.CENTER);
panel.add(serverTable, BorderLayout.CENTER);
if (serverTableModel.getRowCount() > 0) {
table.setRowSelectionInterval(0, 0);
@ -192,7 +267,7 @@ public class BSimServerDialog extends DialogComponentProvider {
}
private boolean hasSelection() {
return filterTable.getSelectedRowObject() != null;
return serverTable.getSelectedRowObject() != null;
}
public BSimServerInfo getLastAdded() {

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -16,27 +16,33 @@
package ghidra.features.bsim.gui.search.dialog;
import java.awt.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import javax.swing.Icon;
import javax.swing.JLabel;
import docking.widgets.table.*;
import ghidra.docking.settings.Settings;
import ghidra.features.bsim.gui.BSimServerManager;
import ghidra.features.bsim.query.BSimServerInfo;
import ghidra.features.bsim.query.BSimServerInfo.DBType;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.framework.plugintool.ServiceProviderStub;
import ghidra.program.model.listing.Program;
import ghidra.util.table.column.AbstractGColumnRenderer;
import ghidra.util.table.column.GColumnRenderer;
import ghidra.util.table.field.AbstractProgramBasedDynamicTableColumn;
/**
* Table model for BSim database server definitions
* Table model for BSim database server definitions.
*
* NOTE: This implementation assumes modal dialog use and non-changing connection state
* while instance is in-use. This was done to avoid adding a conection listener which could
* introduce excessive overhead into the connection pool use.
*/
public class BSimServerTableModel extends GDynamicColumnTableModel<BSimServerInfo, Object> {
private List<BSimServerInfo> servers;
private Map<BSimServerInfo, ConnectionPoolStatus> statusCache = new HashMap<>();
private BSimServerManager serverManager;
private BSimServerManagerListener listener = new BSimServerManagerListener() {
@Override
@ -63,8 +69,18 @@ public class BSimServerTableModel extends GDynamicColumnTableModel<BSimServerInf
}
@Override
public boolean isSortable(int columnIndex) {
return columnIndex != 0;
public void fireTableDataChanged() {
statusCache.clear();
super.fireTableDataChanged();
}
/**
* Get DB connection pool status for a specified server
* @param serverInfo server info
* @return connection pool status
*/
ConnectionPoolStatus getConnectionPoolStatus(BSimServerInfo serverInfo) {
return statusCache.computeIfAbsent(serverInfo, s -> new ConnectionPoolStatus(s));
}
@Override
@ -74,7 +90,7 @@ public class BSimServerTableModel extends GDynamicColumnTableModel<BSimServerInf
descriptor.addVisibleColumn(new TypeColumn());
descriptor.addVisibleColumn(new HostColumn());
descriptor.addVisibleColumn(new PortColumn());
descriptor.addVisibleColumn(new ActiveConnectionColumn());
descriptor.addVisibleColumn(new ConnectionStatusColumn());
return descriptor;
}
@ -84,7 +100,7 @@ public class BSimServerTableModel extends GDynamicColumnTableModel<BSimServerInf
}
private class DatabaseNameColumn
extends AbstractProgramBasedDynamicTableColumn<BSimServerInfo, String> {
extends AbstractDynamicTableColumn<BSimServerInfo, String, Object> {
private GColumnRenderer<String> renderer = new AbstractGColumnRenderer<>() {
@Override
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
@ -112,11 +128,8 @@ public class BSimServerTableModel extends GDynamicColumnTableModel<BSimServerInf
}
@Override
public String getValue(BSimServerInfo serverInfo, Settings settings, Program data,
ServiceProvider provider) throws IllegalArgumentException {
// FIXME: Get cell tooltip to show full getDBName which includes file path
public String getValue(BSimServerInfo serverInfo, Settings settings, Object data,
ServiceProvider provider) throws IllegalArgumentException {
return serverInfo.getShortDBName();
}
@ -131,8 +144,29 @@ public class BSimServerTableModel extends GDynamicColumnTableModel<BSimServerInf
}
}
private class HostColumn
extends AbstractProgramBasedDynamicTableColumn<BSimServerInfo, String> {
private static class TypeColumn
extends AbstractDynamicTableColumn<BSimServerInfo, String, Object> {
@Override
public String getColumnName() {
return "Type";
}
@Override
public String getValue(BSimServerInfo serverInfo, Settings settings, Object data,
ServiceProvider provider) throws IllegalArgumentException {
return serverInfo.getDBType().toString();
}
@Override
public int getColumnPreferredWidth() {
return 80;
}
}
private static class HostColumn
extends AbstractDynamicTableColumn<BSimServerInfo, String, Object> {
@Override
public String getColumnName() {
@ -140,8 +174,8 @@ public class BSimServerTableModel extends GDynamicColumnTableModel<BSimServerInf
}
@Override
public String getValue(BSimServerInfo serverInfo, Settings settings, Program data,
ServiceProvider provider) throws IllegalArgumentException {
public String getValue(BSimServerInfo serverInfo, Settings settings, Object data,
ServiceProvider provider) throws IllegalArgumentException {
return serverInfo.getServerName();
}
@ -152,8 +186,8 @@ public class BSimServerTableModel extends GDynamicColumnTableModel<BSimServerInf
}
}
private class PortColumn
extends AbstractProgramBasedDynamicTableColumn<BSimServerInfo, Integer> {
private static class PortColumn
extends AbstractDynamicTableColumn<BSimServerInfo, String, Object> {
@Override
public String getColumnName() {
@ -161,64 +195,78 @@ public class BSimServerTableModel extends GDynamicColumnTableModel<BSimServerInf
}
@Override
public Integer getValue(BSimServerInfo serverInfo, Settings settings, Program data,
ServiceProvider provider) throws IllegalArgumentException {
public String getValue(BSimServerInfo serverInfo, Settings settings, Object data,
ServiceProvider provider) throws IllegalArgumentException {
int port = serverInfo.getPort();
if (port <= 0) {
return null;
}
return port;
return Integer.toString(port);
}
@Override
public int getColumnPreferredWidth() {
return 80;
return 60;
}
}
private class ActiveConnectionColumn
extends AbstractProgramBasedDynamicTableColumn<BSimServerInfo, Integer> {
private static class ConnectionStatusColumnRenderer
extends AbstractGColumnRenderer<ConnectionPoolStatus> {
private static final ConnectionStatusColumnRenderer INSTANCE =
new ConnectionStatusColumnRenderer();
@Override
public String getColumnName() {
return "Active Connections";
}
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
@Override
public Integer getValue(BSimServerInfo serverInfo, Settings settings, Program data,
ServiceProvider provider) throws IllegalArgumentException {
int activeConnections = BSimServerManager.getActiveConnections(serverInfo);
if (activeConnections < 0) {
return null;
JLabel c = (JLabel) super.getTableCellRendererComponent(data);
ConnectionPoolStatus status = (ConnectionPoolStatus) data.getValue();
// NOTE: Custom column renderer has neem established with future use of
// status icon in mind (e.g., H2 mixed-mode server enabled)
Icon icon = null; // NOTE: may need default filler icon
String text = null;
if (status.isActive) {
text = Integer.toString(status.activeCount) + " / " +
Integer.toString(status.idleCount);
}
return activeConnections;
c.setText(text);
c.setIcon(icon);
return c;
}
@Override
public int getColumnPreferredWidth() {
return 80;
public String getFilterString(ConnectionPoolStatus t, Settings settings) {
return null; // Filtering not supported
}
}
private class TypeColumn
extends AbstractProgramBasedDynamicTableColumn<BSimServerInfo, String> {
private class ConnectionStatusColumn
extends AbstractDynamicTableColumn<BSimServerInfo, ConnectionPoolStatus, Object> {
@Override
public String getColumnName() {
return "Type";
return "Active/Idle Connections";
}
@Override
public String getValue(BSimServerInfo serverInfo, Settings settings, Program data,
ServiceProvider provider) throws IllegalArgumentException {
return serverInfo.getDBType().toString();
public ConnectionPoolStatus getValue(BSimServerInfo serverInfo, Settings settings,
Object data, ServiceProvider provider) throws IllegalArgumentException {
return getConnectionPoolStatus(serverInfo);
}
@Override
public int getColumnPreferredWidth() {
return 80;
return 150;
}
@Override
public GColumnRenderer<ConnectionPoolStatus> getColumnRenderer() {
return ConnectionStatusColumnRenderer.INSTANCE;
}
}

View File

@ -0,0 +1,44 @@
/* ###
* IP: GHIDRA
*
* Licensed 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 ghidra.features.bsim.gui.search.dialog;
import ghidra.features.bsim.gui.BSimServerManager;
import ghidra.features.bsim.query.BSimJDBCDataSource;
import ghidra.features.bsim.query.BSimServerInfo;
class ConnectionPoolStatus {
BSimServerInfo serverInfo;
final boolean isActive;
final int activeCount;
final int idleCount;
ConnectionPoolStatus(BSimServerInfo serverInfo) {
this.serverInfo = serverInfo;
BSimJDBCDataSource dataSource = BSimServerManager.getDataSourceIfExists(serverInfo);
if (dataSource == null) {
isActive = false;
activeCount = 0;
idleCount = 0;
}
else {
isActive = true;
activeCount = dataSource.getActiveConnections();
idleCount = dataSource.getIdleConnections();
}
}
}

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -91,8 +91,7 @@ public class CreateBsimServerInfoDialog extends DialogComponentProvider {
public boolean acceptServer(BSimServerInfo serverInfo) {
// FIXME: Use task to correct dialog parenting issue caused by password prompt
String errorMessage = null;
try {
FunctionDatabase database = BSimClientFactory.buildClient(serverInfo, true);
try (FunctionDatabase database = BSimClientFactory.buildClient(serverInfo, true)) {
if (database.initialize()) {
return true;
}

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -118,7 +118,10 @@ public class BSimClientFactory {
}
/**
* Given the URL for a BSim server construct the appropriate BSim client object (implementing FunctionDatabase)
* Given the URL for a BSim server construct the appropriate BSim client object
* (implementing FunctionDatabase). Returned instance must be
* {@link FunctionDatabase#close() closed} when done using it to prevent depletion
* of database connections.
* @param bsimServerInfo BSim server details
* @param async true if database commits should be asynchronous
* @return the database client

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -48,4 +48,15 @@ public interface BSimJDBCDataSource {
*/
int getActiveConnections();
/**
* Get the number of idle connections in the associated connection pool
* @return number of idle connections
*/
int getIdleConnections();
/**
* Dispose pooled datasource.
*/
void dispose();
}

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -41,7 +41,8 @@ public class BSimPostgresDBConnectionManager {
private static HashMap<BSimServerInfo, BSimPostgresDataSource> dataSourceMap = new HashMap<>();
public static BSimPostgresDataSource getDataSource(BSimServerInfo postgresServerInfo) {
public static synchronized BSimPostgresDataSource getDataSource(
BSimServerInfo postgresServerInfo) {
if (postgresServerInfo.getDBType() != DBType.postgres) {
throw new IllegalArgumentException("expected postgres server info");
}
@ -54,19 +55,20 @@ public class BSimPostgresDBConnectionManager {
return getDataSource(new BSimServerInfo(postgresUrl));
}
public static BSimPostgresDataSource getDataSourceIfExists(BSimServerInfo serverInfo) {
public static synchronized BSimPostgresDataSource getDataSourceIfExists(
BSimServerInfo serverInfo) {
return dataSourceMap.get(serverInfo);
}
private static synchronized void remove(BSimServerInfo serverInfo) {
private static synchronized void remove(BSimServerInfo serverInfo, boolean force) {
BSimPostgresDataSource ds = dataSourceMap.get(serverInfo);
if (ds == null) {
return;
}
int n = ds.bds.getNumActive();
if (n != 0) {
System.out
.println("Unable to remove data source which has " + n + " active connections");
if (n != 0 && !force) {
Msg.error(BSimPostgresDBConnectionManager.class,
"Unable to remove data source which has " + n + " active connections");
return;
}
ds.close();
@ -113,8 +115,9 @@ public class BSimPostgresDBConnectionManager {
bds.setUsername(userName);
}
@Override
public void dispose() {
remove(serverInfo);
remove(serverInfo, true);
}
private void close() {
@ -143,6 +146,11 @@ public class BSimPostgresDBConnectionManager {
return bds.getNumActive();
}
@Override
public int getIdleConnections() {
return bds.getNumIdle();
}
/**
* Update password on {@link BasicDataSource} for use with future connect attempts.
* Has no affect if username does not match username on data source.

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -33,7 +33,9 @@ import ghidra.features.bsim.query.facade.SFOverviewInfo;
import ghidra.features.bsim.query.facade.SFQueryInfo;
import ghidra.features.bsim.query.protocol.*;
import ghidra.framework.Application;
import ghidra.program.model.data.DataUtilities;
import ghidra.util.Msg;
import ghidra.util.StringUtilities;
public interface FunctionDatabase extends AutoCloseable {
@ -239,7 +241,15 @@ public interface FunctionDatabase extends AutoCloseable {
if (res == 3) {
throw new LSHException("Query signature data has no setting information");
}
throw new LSHException("Query signature data does not match database");
throw new LSHException("Query signature data " +
getFormattedVersion(manage.getMajorVersion(), manage.getMinorVersion(),
manage.getSettings()) +
" does not match database " +
getFormattedVersion(info.major, info.minor, info.settings));
}
private static String getFormattedVersion(int maj, int min, int settings) {
return String.format("%d.%d:0x%02x", maj, min, settings);
}
public static boolean checkSettingsForInsert(DescriptionManager manage,
@ -262,8 +272,11 @@ public interface FunctionDatabase extends AutoCloseable {
if (res == 3) {
throw new LSHException("Trying to insert signature data with no setting information");
}
throw new LSHException(
"Trying to insert signature data with settings that don't match database");
throw new LSHException("Trying to insert signature data " +
getFormattedVersion(manage.getMajorVersion(), manage.getMinorVersion(),
manage.getSettings()) +
" with settings that don't match database " +
getFormattedVersion(info.major, info.minor, info.settings));
}
public static String constructFatalError(int flags, ExecutableRecord newrec,

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -28,6 +28,7 @@ import ghidra.features.bsim.query.*;
import ghidra.features.bsim.query.BSimServerInfo.DBType;
import ghidra.features.bsim.query.FunctionDatabase.ConnectionType;
import ghidra.features.bsim.query.FunctionDatabase.Status;
import ghidra.util.Msg;
public class BSimH2FileDBConnectionManager {
@ -44,7 +45,7 @@ public class BSimH2FileDBConnectionManager {
* Get all H2 File DB data sorces which exist in the JVM.
* @return all H2 File DB data sorces
*/
public static Collection<BSimH2FileDataSource> getAllDataSources() {
public static synchronized Collection<BSimH2FileDataSource> getAllDataSources() {
// Create copy to avoid potential concurrent modification
return Collections.unmodifiableCollection(new ArrayList<>(dataSourceMap.values()));
}
@ -57,7 +58,7 @@ public class BSimH2FileDBConnectionManager {
* @throws IllegalArgumentException if {@code fileServerInfo} does not specify an
* H2 File DB type.
*/
public static BSimH2FileDataSource getDataSource(BSimServerInfo fileServerInfo) {
public static synchronized BSimH2FileDataSource getDataSource(BSimServerInfo fileServerInfo) {
if (fileServerInfo.getDBType() != DBType.file) {
throw new IllegalArgumentException("expected file info");
}
@ -79,26 +80,26 @@ public class BSimH2FileDBConnectionManager {
* @return existing H2 File data source or null if server info does not correspond to an
* H2 File or has not be established as an H2 File data source.
*/
public static BSimH2FileDataSource getDataSourceIfExists(BSimServerInfo serverInfo) {
public static synchronized BSimH2FileDataSource getDataSourceIfExists(
BSimServerInfo serverInfo) {
return dataSourceMap.get(serverInfo);
}
private static synchronized void remove(BSimServerInfo serverInfo, boolean force) {
private static synchronized boolean remove(BSimServerInfo serverInfo, boolean force) {
BSimH2FileDataSource ds = dataSourceMap.get(serverInfo);
if (ds == null) {
return;
return true;
}
int n = ds.bds.getNumActive();
if (n != 0) {
System.out
.println("Unable to remove data source which has " + n + " active connections");
if (!force) {
return;
}
if (n != 0 && !force) {
Msg.error(BSimH2FileDBConnectionManager.class,
"Unable to remove data source which has " + n + " active connections");
return false;
}
ds.close();
dataSourceMap.remove(serverInfo);
BSimVectorStoreManager.remove(serverInfo);
return true;
}
/**
@ -123,20 +124,31 @@ public class BSimH2FileDBConnectionManager {
return serverInfo;
}
@Override
public void dispose() {
BSimH2FileDBConnectionManager.remove(serverInfo, true);
}
/**
* Delete the database files associated with this H2 File DB. When complete
* this data source will no longer be valid and should no tbe used.
* Delete the database files associated with this H2 File DB. This will fail immediately
* if active connections exist. Otherwise removal will be attempted and this data source
* will no longer be valid.
* @return true if DB sucessfully removed
*/
public void delete() {
dispose();
public synchronized boolean delete() {
File dbf = new File(serverInfo.getDBName());
// TODO: Should we check for lock on database - could be another process
if (getActiveConnections() != 0) {
Msg.error(this, "Failed to delete active database: " + dbf);
return false;
}
dispose();
if (dbf.isFile()) {
return true;
}
String name = dbf.getName();
int ix = name.lastIndexOf(BSimServerInfo.H2_FILE_EXTENSION);
@ -145,6 +157,13 @@ public class BSimH2FileDBConnectionManager {
}
DeleteDbFiles.execute(dbf.getParent(), name, true);
if (!dbf.isFile()) {
return true;
}
Msg.error(this, "Failed to delete database: " + dbf);
return false;
}
/**
@ -181,6 +200,11 @@ public class BSimH2FileDBConnectionManager {
return bds.getNumActive();
}
@Override
public int getIdleConnections() {
return bds.getNumIdle();
}
private String getH2FileUrl() {
// Remove H2 db file extension if present

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -23,8 +23,7 @@ import org.junit.Test;
import docking.DockingWindowManager;
import docking.action.DockingActionIf;
import ghidra.app.services.ProgramManager;
import ghidra.features.bsim.gui.BSimSearchPlugin;
import ghidra.features.bsim.gui.BSimSearchPluginTestHelper;
import ghidra.features.bsim.gui.*;
import ghidra.features.bsim.gui.overview.BSimOverviewProvider;
import ghidra.features.bsim.gui.overview.BSimOverviewTestHelper;
import ghidra.features.bsim.gui.search.dialog.*;

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -15,7 +15,6 @@
*/
package ghidra.features.bsim.gui;
import ghidra.features.bsim.gui.search.dialog.BSimServerManager;
import ghidra.features.bsim.query.facade.SFQueryServiceFactory;
public class BSimSearchPluginTestHelper {

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -65,6 +65,7 @@ public class QueryFilterTest extends AbstractBSimPluginTest {
assertEquals(SQL_TRUTH, sql);
}
@Override
protected void initializeTool() throws Exception {
super.initializeTool();
goTo(FUN1_ADDR);
@ -80,7 +81,6 @@ public class QueryFilterTest extends AbstractBSimPluginTest {
*
* @param ids resolution IDs
* @return the query string
* @throws SQLException if there is a problem creating the filter
*/
private String generateSQL(IDSQLResolution[] ids) {
try {
@ -88,7 +88,8 @@ public class QueryFilterTest extends AbstractBSimPluginTest {
BSimFilter filter = filterSet.getBSimFilter();
BSimSqlClause sql = SQLEffects.createFilter(filter, ids, null);
return sql.whereClause().trim();
} catch (SQLException e) {
}
catch (SQLException e) {
throw new AssertException(e);
}
}

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -15,8 +15,7 @@
*/
package ghidra.features.bsim.gui.overview;
import ghidra.features.bsim.gui.BSimSearchPlugin;
import ghidra.features.bsim.gui.BSimSearchPluginTestHelper;
import ghidra.features.bsim.gui.*;
import ghidra.features.bsim.gui.search.dialog.*;
import ghidra.features.bsim.query.BSimServerInfo;
import ghidra.features.bsim.query.FunctionDatabase;

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -18,7 +18,7 @@ package ghidra.features.bsim.gui.search.dialog;
import static org.junit.Assert.*;
import java.sql.SQLException;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -30,7 +30,6 @@ import ghidra.features.bsim.query.SQLFunctionDatabase;
import ghidra.features.bsim.query.client.*;
import ghidra.features.bsim.query.facade.FunctionDatabaseTestDouble;
import ghidra.features.bsim.query.protocol.BSimFilter;
import ghidra.program.database.symbol.FunctionSymbol;
/**
* Tests the filtering components of BSim accessible from the UI. This will cover the
@ -44,9 +43,9 @@ import ghidra.program.database.symbol.FunctionSymbol;
*/
public class BSimFilterPanelTest extends AbstractBSimPluginTest {
private Set<FunctionSymbol> selectedFunctions = new HashSet<>();
private BSimFilterPanel filterPanel;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
@ -57,6 +56,7 @@ public class BSimFilterPanelTest extends AbstractBSimPluginTest {
filterPanel = BSimSearchDialogTestHelper.getFilterPanel(searchDialog);
}
@Override
@After
public void tearDown() throws Exception {
close(searchDialog);

View File

@ -4,9 +4,9 @@
* Licensed 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.
@ -17,8 +17,7 @@ package ghidra.features.bsim.gui.search.dialog;
import java.util.Set;
import ghidra.features.bsim.gui.BSimSearchPlugin;
import ghidra.features.bsim.gui.BSimSearchPluginTestHelper;
import ghidra.features.bsim.gui.*;
import ghidra.features.bsim.query.BSimServerInfo;
import ghidra.features.bsim.query.FunctionDatabase;
import ghidra.features.bsim.query.facade.TestBSimServerInfo;

View File

@ -4,16 +4,16 @@
* Licensed 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 ghidra.query.inmemory;
package ghidra.features.bsim.query.file;
import static org.junit.Assert.*;
@ -26,7 +26,6 @@ import ghidra.features.bsim.query.*;
import ghidra.features.bsim.query.BSimServerInfo.DBType;
import ghidra.features.bsim.query.FunctionDatabase.Error;
import ghidra.features.bsim.query.description.DatabaseInformation;
import ghidra.features.bsim.query.file.BSimH2FileDBConnectionManager;
import ghidra.features.bsim.query.file.BSimH2FileDBConnectionManager.BSimH2FileDataSource;
import ghidra.features.bsim.query.protocol.CreateDatabase;
import ghidra.features.bsim.query.protocol.ResponseInfo;
@ -50,7 +49,7 @@ public class BSimH2DatabaseManagerTest extends AbstractGhidraHeadedIntegrationTe
@After
public void tearDown() {
//cleanup();
cleanup();
}
private File getTempDbDir() {
@ -77,7 +76,7 @@ public class BSimH2DatabaseManagerTest extends AbstractGhidraHeadedIntegrationTe
}
private BSimServerInfo createDatabase(String databaseName, List<String> tags,
List<String> execats, String expectedError) {
List<String> execats, String expectedError) {
BSimServerInfo h2DbInfo = getBsimServerInfo(databaseName);
Msg.debug(this, "Creating H2 File DB: " + h2DbInfo);

View File

@ -4,16 +4,16 @@
* Licensed 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 ghidra.query.test;
package ghidra.features.bsim.query.test;
import static org.junit.Assert.*;

View File

@ -4,16 +4,16 @@
* Licensed 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 ghidra.query.test;
package ghidra.features.bsim.query.test;
import java.io.*;