dbeaver/pro#9048 CB NPE fix + QM deadlock fix (#4288)

This commit is contained in:
Serge Rider
2026-04-16 21:13:18 +02:00
committed by GitHub
parent 768fe00f6a
commit 644dc2a136
2 changed files with 58 additions and 36 deletions
@@ -1,6 +1,6 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2024 DBeaver Corp and others
* Copyright (C) 2010-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -63,11 +63,12 @@ public interface DBWServiceNavigator extends DBWService {
@Nullable Boolean recursive) throws DBWebException;
@WebAction
@NotNull
WebStructContainers getStructContainers(
String projectId,
WebConnectionInfo connectionInfo,
String contextId,
String catalog) throws DBWebException;
@NotNull String projectId,
@NotNull WebConnectionInfo connectionInfo,
@NotNull String contextId,
@Nullable String catalog) throws DBWebException;
@WebAction
String renameNode(
@@ -1,6 +1,6 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2025 DBeaver Corp and others
* Copyright (C) 2010-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,7 +60,6 @@ import org.jkiss.utils.CommonUtils;
import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
* Web service implementation
@@ -314,12 +313,13 @@ public class WebServiceNavigator implements DBWServiceNavigator {
}
}
@NotNull
@Override
public WebStructContainers getStructContainers(
String projectId,
WebConnectionInfo connection,
String contextId,
String catalog
@NotNull String projectId,
@NotNull WebConnectionInfo connection,
@NotNull String contextId,
@Nullable String catalog
) throws DBWebException {
DBPDataSource dataSource = connection.getDataSource();
DBCExecutionContext executionContext = DBUtils.getDefaultContext(connection.getDataSource(), false);
@@ -344,9 +344,9 @@ public class WebServiceNavigator implements DBWServiceNavigator {
DBRProgressMonitor monitor = connection.getSession().getProgressMonitor();
List<? extends DBSObject> dbsObjects = this.getCatalogs(
monitor,
connection.getDataSourceContainer().getDataSource(),
contextDefaults);
monitor,
connection.getDataSourceContainer().getDataSource(),
contextDefaults);
for (DBSObject dbsObject : dbsObjects) {
if (!dataSource.getContainer().getNavigatorSettings().isShowSystemObjects()
@@ -404,26 +404,36 @@ public class WebServiceNavigator implements DBWServiceNavigator {
return structContainers;
}
protected List<? extends DBSObject> getCatalogs(DBRProgressMonitor monitor, DBSObject rootObject, DBCExecutionContextDefaults<?, ?> contextDefaults) throws DBWebException {
if (rootObject instanceof DBSObjectContainer) {
@NotNull
protected List<? extends DBSObject> getCatalogs(
@NotNull DBRProgressMonitor monitor,
@NotNull DBSObject rootObject,
@Nullable DBCExecutionContextDefaults<?, ?> contextDefaults
) throws DBWebException {
if (rootObject instanceof DBSObjectContainer objectContainer) {
try {
Collection<? extends DBSObject> objectsCollection;
if (rootObject instanceof DBSCatalog && contextDefaults != null && !contextDefaults.supportsCatalogChange()) {
objectsCollection = Collections.singletonList(contextDefaults.getDefaultCatalog());
} else {
objectsCollection = ((DBSObjectContainer) rootObject).getChildren(monitor);
objectsCollection = objectContainer.getChildren(monitor);
}
if (objectsCollection == null) {
return Collections.emptyList();
}
return new ArrayList<>(objectsCollection);
} catch (DBException e) {
throw new DBWebException("Error reading context defaults", e);
// return Collections.emptyList();
}
}
return Collections.emptyList();
}
@Nullable
protected WebNavigatorNodeInfo getNodeFromObject(WebSession session, DBSObject object) throws DBWebException {
protected WebNavigatorNodeInfo getNodeFromObject(
@NotNull WebSession session,
@NotNull DBSObject object
) throws DBWebException {
DBRProgressMonitor monitor = session.getProgressMonitor();
DBNNode node = session.getNavigatorModelOrThrow().getNodeByObject(monitor, object, false);
@@ -454,10 +464,10 @@ public class WebServiceNavigator implements DBWServiceNavigator {
}
return node.getNodeItemPath();
}
if (node instanceof DBNDatabaseNode) {
if (node instanceof DBNDatabaseNode dbNode) {
return renameDatabaseObject(
session,
(DBNDatabaseNode) node,
dbNode,
CommonUtils.trim(CommonUtils.notEmpty(newName)));
}
throw new DBException("Rename is not supported");
@@ -466,7 +476,11 @@ public class WebServiceNavigator implements DBWServiceNavigator {
}
}
private void renameConnectionFolder(@NotNull WebSession session, DBNNode node, @NotNull String newName) throws DBException {
private void renameConnectionFolder(
@NotNull WebSession session,
DBNNode node,
@NotNull String newName
) throws DBException {
WebConnectionFolderUtils.validateConnectionFolder(newName);
DBNNode[] children = ((DBNLocalFolder) node).getLogicalParent().getChildren(session.getProgressMonitor());
if (children != null) {
@@ -480,7 +494,11 @@ public class WebServiceNavigator implements DBWServiceNavigator {
node.rename(session.getProgressMonitor(), newName);
}
private void renameRmResourceNode(@NotNull WebSession session, DBNNode node, @NotNull String newName) throws DBException {
private void renameRmResourceNode(
@NotNull WebSession session,
DBNNode node,
@NotNull String newName
) throws DBException {
if (newName.contains("/") || newName.contains("\\")) {
throw new DBWebException("New node name has prohibited symbols: \\ /");
}
@@ -496,9 +514,9 @@ public class WebServiceNavigator implements DBWServiceNavigator {
private void addRmMoveEvent(
@NotNull WebSession session,
String projectId,
String oldResourcePath,
String newResourcePath
@NotNull String projectId,
@NotNull String oldResourcePath,
@NotNull String newResourcePath
) {
WebEventUtils.addRmResourceUpdatedEvent(
projectId,
@@ -566,8 +584,7 @@ public class WebServiceNavigator implements DBWServiceNavigator {
}
} else if (node instanceof DBNLocalFolder) {
node.getOwnerProject().getDataSourceRegistry().removeFolder(((DBNLocalFolder) node).getFolder(), false);
} else if (node instanceof DBNResourceManagerResource) {
DBNResourceManagerResource rmResource = ((DBNResourceManagerResource) node);
} else if (node instanceof DBNResourceManagerResource rmResource) {
String resourceProjectId = rmResource.getResourceProject().getId();
String resourcePath = rmResource.getResourceFolder();
session.getRmController().deleteResource(resourceProjectId, resourcePath, true);
@@ -589,14 +606,18 @@ public class WebServiceNavigator implements DBWServiceNavigator {
}
}
private void checkProjectEditAccess(DBNNode node, WebSession session) throws DBException {
private void checkProjectEditAccess(@NotNull DBNNode node, @NotNull WebSession session) throws DBException {
BaseWebProjectImpl project = (BaseWebProjectImpl) node.getOwnerProject();
if (project == null || !hasNodeEditPermission(session, node, project.getRMProject())) {
throw new DBException("Access denied");
}
}
private boolean hasNodeEditPermission(WebSession session, DBNNode node, RMProject rmProject) {
private boolean hasNodeEditPermission(
@NotNull WebSession session,
@NotNull DBNNode node,
@NotNull RMProject rmProject
) {
if (node instanceof DBNDataSource || node instanceof DBNLocalFolder) {
return SMUtils.hasProjectPermission(session, rmProject, RMProjectPermission.DATA_SOURCES_EDIT);
} else if (node instanceof DBNAbstractResourceManagerNode) {
@@ -644,7 +665,7 @@ public class WebServiceNavigator implements DBWServiceNavigator {
if (parentFolder != null) {
List<String> siblings = Arrays.stream(parentFolder.getChildren())
.map(DBPDataSourceFolder::getName)
.collect(Collectors.toList());
.toList();
if (siblings.contains(node.getName())) {
throw new DBWebException("Node " + folderNodePath + " contains folder with name '" + node.getName() + "'");
}
@@ -655,9 +676,8 @@ public class WebServiceNavigator implements DBWServiceNavigator {
);
node.getOwnerProject().getDataSourceRegistry().checkForErrors();
WebServiceUtils.refreshDatabases(session, node.getOwnerProject().getId());
} else if (node instanceof DBNResourceManagerResource) {
} else if (node instanceof DBNResourceManagerResource rmOldNode) {
boolean rmNewNode = folderNode instanceof DBNAbstractResourceManagerNode;
DBNResourceManagerResource rmOldNode = (DBNResourceManagerResource) node;
if (!rmNewNode) {
throw new DBWebException("Navigator node '" + folderNodePath + "' is not a resource manager node");
}
@@ -665,8 +685,8 @@ public class WebServiceNavigator implements DBWServiceNavigator {
String projectId = rmOldNode.getResourceProject().getId();
// Get paths from nodes
String newPath = rmOldNode.getResource().getName();
if (folderNode instanceof DBNResourceManagerResource) {
newPath = ((DBNResourceManagerResource) folderNode).getResourceFolder() + "/" + newPath;
if (folderNode instanceof DBNResourceManagerResource rmr) {
newPath = rmr.getResourceFolder() + "/" + newPath;
}
String resourcePath = rmOldNode.getResourceFolder();
session.getRmController().moveResource(projectId, resourcePath, newPath);
@@ -710,7 +730,8 @@ public class WebServiceNavigator implements DBWServiceNavigator {
throw new DBException("Node " + node.getNodeUri() + " rename is not supported");
}
public DBCExecutionContext getCommandExecutionContext(DBSObject object) {
@Nullable
public DBCExecutionContext getCommandExecutionContext(@NotNull DBSObject object) {
DBCExecutionContext executionContext = DBUtils.getDefaultContext(object, true);
if (executionContext == null) {
// It may happen in case of lazy context initialization